2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Tests for IOCTL_TCP_QUERY_INFORMATION_EX
5 * PROGRAMMER: Jérôme Gardou <jerome.gardou@reactos.org>
19 typedef struct IPRouteEntry
{
20 unsigned long ire_dest
;
21 unsigned long ire_index
;
22 unsigned long ire_metric1
;
23 unsigned long ire_metric2
;
24 unsigned long ire_metric3
;
25 unsigned long ire_metric4
;
26 unsigned long ire_nexthop
;
27 unsigned long ire_type
;
28 unsigned long ire_proto
;
29 unsigned long ire_age
;
30 unsigned long ire_mask
;
31 unsigned long ire_metric5
;
32 unsigned long ire_context
;
35 /* Present in headers for Vista+, but there in WinXP/2k3 ntdll */
39 RtlIpv4AddressToStringA(
40 _In_
const struct in_addr
*Addr
,
41 _Out_writes_(16) PSTR S
);
44 static HANDLE TcpFileHandle
;
46 static ULONG IndentationLevel
= 0;
50 dbg_print_physaddr(const unsigned char* addr
, unsigned long addr_len
)
52 static char buffer
[24];
59 dest
+= sprintf(dest
, "%02x", *addr
);
71 indent_printf(const char* format
, ...)
73 ULONG Indent
= IndentationLevel
;
80 va_start(args
, format
);
81 ret
= vprintf(format
, args
);
84 ret
+= IndentationLevel
;
96 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
97 ULONG BufferSize
= sizeof(IFEntry
) + MAX_ADAPTER_DESCRIPTION_LENGTH
+ 1;
100 /* Not valid for other entity types */
101 if (EntityType
!= IF_MIB
)
104 IfEntry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
105 ok(IfEntry
!= NULL
, "\n");
107 ZeroMemory(&Request
, sizeof(Request
));
108 Request
.ID
.toi_entity
= Id
;
109 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
110 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
111 Request
.ID
.toi_id
= IF_MIB_STATS_ID
;
113 Result
= DeviceIoControl(
115 IOCTL_TCP_QUERY_INFORMATION_EX
,
122 ok(Result
, "DeviceIoControl failed.\n");
125 indent_printf("IF_MIB Statistics:\n");
127 indent_printf("if_index: %lu\n", IfEntry
->if_index
);
128 indent_printf("if_type: %lu\n", IfEntry
->if_type
);
129 indent_printf("if_mtu: %lu\n", IfEntry
->if_mtu
);
130 indent_printf("if_speed: %lu\n", IfEntry
->if_speed
);
131 indent_printf("if_physaddr: %s\n", dbg_print_physaddr(IfEntry
->if_physaddr
, IfEntry
->if_physaddrlen
));
132 indent_printf("if_adminstatus: %lu\n", IfEntry
->if_adminstatus
);
133 indent_printf("if_operstatus: %lu\n", IfEntry
->if_operstatus
);
134 indent_printf("if_lastchange: %lu\n", IfEntry
->if_lastchange
);
135 indent_printf("if_inoctets: %lu\n", IfEntry
->if_inoctets
);
136 indent_printf("if_inucastpkts: %lu\n", IfEntry
->if_inucastpkts
);
137 indent_printf("if_innucastpkts: %lu\n", IfEntry
->if_innucastpkts
);
138 indent_printf("if_indiscards: %lu\n", IfEntry
->if_indiscards
);
139 indent_printf("if_inerrors: %lu\n", IfEntry
->if_inerrors
);
140 indent_printf("if_inunknownprotos: %lu\n", IfEntry
->if_inunknownprotos
);
141 indent_printf("if_outoctets: %lu\n", IfEntry
->if_outoctets
);
142 indent_printf("if_outucastpkts: %lu\n", IfEntry
->if_outucastpkts
);
143 indent_printf("if_outnucastpkts: %lu\n", IfEntry
->if_outnucastpkts
);
144 indent_printf("if_outdiscards: %lu\n", IfEntry
->if_outdiscards
);
145 indent_printf("if_outerrors: %lu\n", IfEntry
->if_outerrors
);
146 indent_printf("if_outqlen: %lu\n", IfEntry
->if_outqlen
);
147 indent_printf("if_descr: %*s\n", IfEntry
->if_descrlen
, IfEntry
->if_descr
);
150 HeapFree(GetProcessHeap(), 0, IfEntry
);
159 IPSNMPInfo IpSnmpInfo
;
160 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
161 ULONG BufferSize
= 0;
164 /* Not valid for other entity types */
165 if (EntityType
!= CL_NL_IP
)
168 ZeroMemory(&IpSnmpInfo
, sizeof(IpSnmpInfo
));
170 ZeroMemory(&Request
, sizeof(Request
));
171 Request
.ID
.toi_entity
= Id
;
172 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
173 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
174 Request
.ID
.toi_id
= IP_MIB_STATS_ID
;
176 Result
= DeviceIoControl(
178 IOCTL_TCP_QUERY_INFORMATION_EX
,
185 ok(Result
, "DeviceIoControl failed.\n");
188 indent_printf("IP_MIB Statistics:\n");
190 indent_printf("ipsi_forwarding: %lu\n", IpSnmpInfo
.ipsi_forwarding
);
191 indent_printf("ipsi_defaultttl: %lu\n", IpSnmpInfo
.ipsi_defaultttl
);
192 indent_printf("ipsi_inreceives: %lu\n", IpSnmpInfo
.ipsi_inreceives
);
193 indent_printf("ipsi_inhdrerrors: %lu\n", IpSnmpInfo
.ipsi_inhdrerrors
);
194 indent_printf("ipsi_inaddrerrors: %lu\n", IpSnmpInfo
.ipsi_inaddrerrors
);
195 indent_printf("ipsi_forwdatagrams: %lu\n", IpSnmpInfo
.ipsi_forwdatagrams
);
196 indent_printf("ipsi_inunknownprotos: %lu\n", IpSnmpInfo
.ipsi_inunknownprotos
);
197 indent_printf("ipsi_indiscards: %lu\n", IpSnmpInfo
.ipsi_indiscards
);
198 indent_printf("ipsi_indelivers: %lu\n", IpSnmpInfo
.ipsi_indelivers
);
199 indent_printf("ipsi_outrequests: %lu\n", IpSnmpInfo
.ipsi_outrequests
);
200 indent_printf("ipsi_routingdiscards: %lu\n", IpSnmpInfo
.ipsi_routingdiscards
);
201 indent_printf("ipsi_outdiscards: %lu\n", IpSnmpInfo
.ipsi_outdiscards
);
202 indent_printf("ipsi_outnoroutes: %lu\n", IpSnmpInfo
.ipsi_outnoroutes
);
203 indent_printf("ipsi_reasmtimeout: %lu\n", IpSnmpInfo
.ipsi_reasmtimeout
);
204 indent_printf("ipsi_reasmreqds: %lu\n", IpSnmpInfo
.ipsi_reasmreqds
);
205 indent_printf("ipsi_reasmoks: %lu\n", IpSnmpInfo
.ipsi_reasmoks
);
206 indent_printf("ipsi_reasmfails: %lu\n", IpSnmpInfo
.ipsi_reasmfails
);
207 indent_printf("ipsi_fragoks: %lu\n", IpSnmpInfo
.ipsi_fragoks
);
208 indent_printf("ipsi_fragfails: %lu\n", IpSnmpInfo
.ipsi_fragfails
);
209 indent_printf("ipsi_fragcreates: %lu\n", IpSnmpInfo
.ipsi_fragcreates
);
210 indent_printf("ipsi_numif: %lu\n", IpSnmpInfo
.ipsi_numif
);
211 indent_printf("ipsi_numaddr: %lu\n", IpSnmpInfo
.ipsi_numaddr
);
212 indent_printf("ipsi_numroutes: %lu\n", IpSnmpInfo
.ipsi_numroutes
);
214 if (IpSnmpInfo
.ipsi_numaddr
!= 0)
216 IPAddrEntry
* AddrEntries
;
219 AddrEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]));
220 ok(AddrEntries
!= NULL
, "\n");
222 ZeroMemory(&Request
, sizeof(Request
));
223 Request
.ID
.toi_entity
= Id
;
224 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
225 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
226 Request
.ID
.toi_id
= IP_MIB_ADDRTABLE_ENTRY_ID
;
228 Result
= DeviceIoControl(
230 IOCTL_TCP_QUERY_INFORMATION_EX
,
234 IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]),
237 ok(Result
, "DeviceIoControl failed.\n");
238 ok_long(BufferSize
, IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]));
240 for(i
= 0; i
< IpSnmpInfo
.ipsi_numaddr
; i
++)
242 CHAR AddressString
[16];
245 Addr
.S_un
.S_addr
= AddrEntries
[i
].iae_addr
;
246 RtlIpv4AddressToStringA(&Addr
, AddressString
);
248 indent_printf("Address %lu: %s\n", i
, AddressString
);
252 indent_printf("iae_addr: %lx\n", AddrEntries
[i
].iae_addr
);
253 indent_printf("iae_index: %lu\n", AddrEntries
[i
].iae_index
);
254 Addr
.S_un
.S_addr
= AddrEntries
[i
].iae_mask
;
255 RtlIpv4AddressToStringA(&Addr
, AddressString
);
256 indent_printf("iae_mask: %lx (%s)\n", AddrEntries
[i
].iae_mask
, AddressString
);
257 indent_printf("iae_bcastaddr: %lu\n", AddrEntries
[i
].iae_bcastaddr
);
258 indent_printf("iae_reasmsize: %lu\n", AddrEntries
[i
].iae_reasmsize
);
259 indent_printf("iae_context: %u\n", AddrEntries
[i
].iae_context
);
262 IPInterfaceInfo
* InterfaceInfo
;
264 /* Get the interface info */
265 BufferSize
= sizeof(IPInterfaceInfo
) + MAX_PHYSADDR_SIZE
;
266 InterfaceInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
267 ok(InterfaceInfo
!= NULL
, "\n");
269 Request
.ID
.toi_id
= IP_INTFC_INFO_ID
;
270 Request
.Context
[0] = AddrEntries
[i
].iae_addr
;
271 Result
= DeviceIoControl(
273 IOCTL_TCP_QUERY_INFORMATION_EX
,
280 ok(Result
, "DeviceIoControl failed.\n");
282 indent_printf("Interface info:\n");
285 indent_printf("iii_flags: %lu\n", InterfaceInfo
->iii_flags
);
286 indent_printf("iii_mtu : %lu\n", InterfaceInfo
->iii_mtu
);
287 indent_printf("iii_speed: %lu\n", InterfaceInfo
->iii_speed
);
288 indent_printf("iii_physaddr: %s\n", dbg_print_physaddr(InterfaceInfo
->iii_addr
, InterfaceInfo
->iii_addrlength
));
296 HeapFree(GetProcessHeap(), 0, AddrEntries
);
299 /* See for the routes */
300 if (IpSnmpInfo
.ipsi_numroutes
)
302 IPRouteEntry
* RouteEntries
;
305 RouteEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]));
306 ok(RouteEntries
!= NULL
, "\n");
308 ZeroMemory(&Request
, sizeof(Request
));
309 Request
.ID
.toi_entity
= Id
;
310 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
311 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
312 Request
.ID
.toi_id
= IP_MIB_ARPTABLE_ENTRY_ID
;
314 Result
= DeviceIoControl(
316 IOCTL_TCP_QUERY_INFORMATION_EX
,
320 IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]),
323 ok(Result
, "DeviceIoControl failed.\n");
324 ok_long(BufferSize
, IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]));
326 for (i
= 0; i
< IpSnmpInfo
.ipsi_numroutes
; i
++)
328 CHAR AddressString
[16];
331 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_dest
;
332 RtlIpv4AddressToStringA(&Addr
, AddressString
);
334 indent_printf("Route %lu:\n", i
);
338 indent_printf("ire_dest: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_dest
);
339 indent_printf("ire_index: %lu\n", RouteEntries
[i
].ire_index
);
340 indent_printf("ire_metric1: %#lx\n", RouteEntries
[i
].ire_metric1
);
341 indent_printf("ire_metric2: %#lx\n", RouteEntries
[i
].ire_metric2
);
342 indent_printf("ire_metric3: %#lx\n", RouteEntries
[i
].ire_metric3
);
343 indent_printf("ire_metric4: %#lx\n", RouteEntries
[i
].ire_metric4
);
344 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_nexthop
;
345 RtlIpv4AddressToStringA(&Addr
, AddressString
);
346 indent_printf("ire_nexthop: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_nexthop
);
347 indent_printf("ire_type: %lu\n", RouteEntries
[i
].ire_type
);
348 indent_printf("ire_proto: %lu\n", RouteEntries
[i
].ire_proto
);
349 indent_printf("ire_age: %lu\n", RouteEntries
[i
].ire_age
);
350 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_mask
;
351 RtlIpv4AddressToStringA(&Addr
, AddressString
);
352 indent_printf("ire_mask: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_mask
);
353 indent_printf("ire_metric5: %lx\n", RouteEntries
[i
].ire_metric5
);
354 indent_printf("ire_context: %lx\n", RouteEntries
[i
].ire_context
);
363 typedef struct ARPInfo
365 unsigned long ai_numroutes
;
366 unsigned long ai_unknown
;
369 typedef struct ARPEntry
371 unsigned long ae_index
;
372 unsigned long ae_physaddrlen
;
373 unsigned char ae_physaddr
[MAX_PHYSADDR_SIZE
];
374 unsigned long ae_address
;
375 unsigned long ae_unknown
;
385 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
386 ULONG BufferSize
= 0;
389 /* Not valid for other entity types */
390 if (EntityType
!= AT_ARP
)
393 ZeroMemory(&Request
, sizeof(Request
));
394 Request
.ID
.toi_entity
= Id
;
395 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
396 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
397 Request
.ID
.toi_id
= AT_MIB_ADDRXLAT_INFO_ID
;
399 Result
= DeviceIoControl(
401 IOCTL_TCP_QUERY_INFORMATION_EX
,
408 ok(Result
, "DeviceIoControl failed.\n");
409 ok_long(BufferSize
, sizeof(ArpInfo
));
411 indent_printf("ARP Info:\n");
414 indent_printf("ai_numroutes: %lu\n", ArpInfo
.ai_numroutes
);
415 indent_printf("ai_unknown: %lx\n", ArpInfo
.ai_unknown
);
417 if (ArpInfo
.ai_numroutes
)
419 ARPEntry
* ArpEntries
;
422 Request
.ID
.toi_id
= AT_MIB_ADDRXLAT_ENTRY_ID
;
424 ArpEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]));
425 ok(ArpEntries
!= NULL
, "\n");
427 Result
= DeviceIoControl(
429 IOCTL_TCP_QUERY_INFORMATION_EX
,
433 ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]),
436 ok(Result
, "DeviceIoControl failed.\n");
437 ok_long(BufferSize
, ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]));
439 for (i
= 0; i
< ArpInfo
.ai_numroutes
; i
++)
441 CHAR AddressString
[16];
444 Addr
.S_un
.S_addr
= ArpEntries
[i
].ae_address
;
445 RtlIpv4AddressToStringA(&Addr
, AddressString
);
447 indent_printf("ARP Entry %lu:\n", i
);
451 indent_printf("ae_index: %lu\n", ArpEntries
[i
].ae_index
);
452 indent_printf("ae_physaddr: %s\n", dbg_print_physaddr(ArpEntries
[i
].ae_physaddr
, ArpEntries
[i
].ae_physaddrlen
));
453 indent_printf("ae_address: %lx (%s)\n", ArpEntries
[i
].ae_address
, AddressString
);
454 indent_printf("ae_unknown: %lu.\n", ArpEntries
[i
].ae_unknown
);
459 HeapFree(GetProcessHeap(), 0, ArpEntries
);
467 TDIEntityID
* Entities
;
470 ULONG i
, EntityCount
;
471 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
473 /* Open a control channel file for TCP */
474 TcpFileHandle
= CreateFileW(
476 FILE_READ_DATA
| FILE_WRITE_DATA
,
477 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
482 ok(TcpFileHandle
!= INVALID_HANDLE_VALUE
, "CreateFile failed, GLE %lu\n", GetLastError());
486 Result
= DeviceIoControl(
488 IOCTL_TCP_QUERY_INFORMATION_EX
,
495 ok(!Result
, "DeviceIoControl succeeded.\n");
496 ok_long(GetLastError(), ERROR_INVALID_PARAMETER
);
497 ok_long(BufferSize
, 0);
499 ZeroMemory(&Request
, sizeof(Request
));
500 Request
.ID
.toi_entity
.tei_entity
= GENERIC_ENTITY
;
501 Request
.ID
.toi_entity
.tei_instance
= 0;
502 Request
.ID
.toi_class
= INFO_CLASS_GENERIC
;
503 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
504 Request
.ID
.toi_id
= ENTITY_LIST_ID
;
507 Result
= DeviceIoControl(
509 IOCTL_TCP_QUERY_INFORMATION_EX
,
516 ok(!Result
, "DeviceIoControl succeeded.\n");
517 ok_long(GetLastError(), ERROR_INVALID_PARAMETER
);
518 ok_long(BufferSize
, 0);
520 BufferSize
= 4 * sizeof(Entities
[0]);
521 Entities
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
522 ok(Entities
!= NULL
, "\n");
526 Result
= DeviceIoControl(
528 IOCTL_TCP_QUERY_INFORMATION_EX
,
539 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
543 Entities
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Entities
, BufferSize
);
544 ok(Entities
!= NULL
, "\n");
547 ok(Result
, "DeviceIoControl failed!\n");
548 EntityCount
= BufferSize
/ sizeof(Entities
[0]);
549 trace("Got %lu entities.\n", EntityCount
);
551 for (i
= 0; i
< EntityCount
; i
++)
556 Request
.ID
.toi_entity
= Entities
[i
];
557 Request
.ID
.toi_class
= INFO_CLASS_GENERIC
;
558 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
559 Request
.ID
.toi_id
= ENTITY_TYPE_ID
;
561 Result
= DeviceIoControl(
563 IOCTL_TCP_QUERY_INFORMATION_EX
,
570 ok(Result
, "DeviceIoControl failed.\n");
572 printf("Entity %lu: %#lx, %#lx, type %#lx\n", i
, Entities
[i
].tei_entity
, Entities
[i
].tei_instance
, EntityType
);
573 test_IF_MIB_STATS(Entities
[i
], EntityType
);
574 test_IP_MIB_STATS(Entities
[i
], EntityType
);
575 test_AT_ARP_STATS(Entities
[i
], EntityType
);
578 HeapFree(GetProcessHeap(), 0, Entities
);
579 CloseHandle(TcpFileHandle
);