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/07-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 IPADDR_ENTRY IpAddress
;
42 UINT BufSize
= *BufferSize
;
44 /* Make return parameters consistent every time */
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
;
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
) {
60 if (BufSize
< sizeof(ULONG
))
61 return TDI_BUFFER_TOO_SMALL
;
64 Count
= CopyBufferToBufferChain(Buffer
, 0, (PUCHAR
)&Temp
, sizeof(ULONG
));
68 return TDI_INVALID_PARAMETER
;
71 if (ID
->toi_class
== INFO_CLASS_PROTOCOL
) {
72 if (ID
->toi_type
!= INFO_TYPE_PROVIDER
)
73 return TDI_INVALID_PARAMETER
;
76 case IP_MIB_ADDRTABLE_ENTRY_ID
:
79 KeAcquireSpinLock(&InterfaceLock
, &OldIrql
);
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
);
95 CurrentADEEntry
= CurrentADEEntry
->Flink
;
97 LoopbackIsRegistered
= TRUE
;
98 CurrentIFEntry
= CurrentIFEntry
->Flink
;
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
;
110 IpAddress
.BcastAddr
= 0;
112 /* Locate the diffrent addresses and put them the right place */
113 for (ADE
= IF
->ADE
; ADE
!= NULL
; ADE
= ADE
->Next
) {
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
;
120 /* Pack the address information into IPADDR_ENTRY structure */
122 IpAddress
.ReasmSize
= 0;
123 IpAddress
.Context
= 0;
126 Count
= CopyBufferToBufferChain(Buffer
, Temp
, (PUCHAR
)&IpAddress
, sizeof(IPADDR_ENTRY
));
128 Temp
+= sizeof(IPADDR_ENTRY
);
130 KeReleaseSpinLock(&InterfaceLock
, OldIrql
);
133 case IP_MIB_STATS_ID
:
134 if (BufSize
< sizeof(IPSNMP_INFO
))
135 return TDI_BUFFER_TOO_SMALL
;
137 RtlZeroMemory(&SnmpInfo
, sizeof(IPSNMP_INFO
));
139 /* Count number of addresses */
141 KeAcquireSpinLock(&InterfaceLock
, &OldIrql
);
142 for (IF
= InterfaceList
; IF
!= NULL
; IF
= IF
->Next
)
144 KeReleaseSpinLock(&InterfaceLock
, OldIrql
);
146 SnmpInfo
.NumAddr
= Count
;
148 Count
= CopyBufferToBufferChain(Buffer
, 0, (PUCHAR
)&SnmpInfo
, sizeof(IPSNMP_INFO
));
153 /* We can't handle this ID */
154 return TDI_INVALID_PARAMETER
;
158 return TDI_INVALID_PARAMETER
;
162 TDI_STATUS
InfoTdiQueryInformationEx(
163 PTDI_REQUEST Request
,
169 * FUNCTION: Returns extended information
171 * Request = Pointer to TDI request structure for the request
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
178 * Status of operation
181 PADDRESS_FILE AddrFile
;
190 UINT BufSize
= *BufferSize
;
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
;
202 Size
= EntityCount
* sizeof(TDIEntityID
);
204 /* The buffer is too small to contain requested data */
205 return TDI_BUFFER_TOO_SMALL
;
207 /* Return entity list */
208 Count
= CopyBufferToBufferChain(Buffer
, 0, (PUCHAR
)EntityList
, Size
);
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
);
221 /* Make return parameters consistent every time */
224 if (ID
->toi_entity
.tei_instance
!= TL_INSTANCE
)
225 /* We only support a single instance */
226 return TDI_INVALID_REQUEST
;
228 if (ID
->toi_class
== INFO_CLASS_GENERIC
) {
230 if (ID
->toi_type
!= INFO_TYPE_PROVIDER
||
231 ID
->toi_id
!= ENTITY_TYPE_ID
)
232 return TDI_INVALID_PARAMETER
;
234 if (BufSize
< sizeof(ULONG
))
235 return TDI_BUFFER_TOO_SMALL
;
237 if (Entity
== CL_TL_ENTITY
)
239 else if (Entity
== CO_TL_ENTITY
)
242 return TDI_INVALID_PARAMETER
;
244 Count
= CopyBufferToBufferChain(Buffer
, 0, (PUCHAR
)&Temp
, sizeof(ULONG
));
249 if (ID
->toi_class
== INFO_CLASS_PROTOCOL
) {
251 if (ID
->toi_type
!= INFO_TYPE_PROVIDER
)
252 return TDI_INVALID_PARAMETER
;
254 switch (ID
->toi_id
) {
255 case UDP_MIB_STAT_ID
:
256 if (Entity
!= CL_TL_ENTITY
)
257 return TDI_INVALID_PARAMETER
;
259 if (BufSize
< sizeof(UDPStats
))
260 return TDI_BUFFER_TOO_SMALL
;
262 Count
= CopyBufferToBufferChain(Buffer
, 0, (PUCHAR
)&UDPStats
, sizeof(UDP_STATISTICS
));
266 case UDP_MIB_TABLE_ID
:
267 if (Entity
!= CL_TL_ENTITY
)
268 return TDI_INVALID_PARAMETER
;
272 KeAcquireSpinLock(&AddressFileLock
, &OldIrql
);
274 for (AddrFile
= AddressFileList
;
275 AddrFile
->Next
!= NULL
;
276 AddrFile
= AddrFile
->Next
) {
278 if (Offset
+ sizeof(ADDRESS_INFO
) > BufSize
) {
279 KeReleaseSpinLock(&AddressFileLock
, OldIrql
);
280 *BufferSize
= Offset
;
281 return TDI_BUFFER_OVERFLOW
;
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
;
291 Info
.LocalPort
= AddrFile
->Port
;
293 Count
= CopyBufferToBufferChain(Buffer
, Offset
, (PUCHAR
)&Info
, sizeof(ADDRESS_INFO
));
298 KeReleaseSpinLock(&AddressFileLock
, OldIrql
);
300 *BufferSize
= Offset
;
302 return STATUS_SUCCESS
;
305 /* We can't handle this ID */
306 return TDI_INVALID_PARAMETER
;
310 return TDI_INVALID_PARAMETER
;
314 TDI_STATUS
InfoTdiSetInformationEx(
315 PTDI_REQUEST Request
,
320 * FUNCTION: Sets extended information
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
327 * Status of operation
330 /* FIXME: Set extended information */
332 return TDI_INVALID_REQUEST
;