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 #define AT_MIB_ADDRXLAT_INFO_ID 1
20 #define AT_MIB_ADDRXLAT_ENTRY_ID 0x101
23 typedef struct IPRouteEntry
{
24 unsigned long ire_dest
;
25 unsigned long ire_index
;
26 unsigned long ire_metric1
;
27 unsigned long ire_metric2
;
28 unsigned long ire_metric3
;
29 unsigned long ire_metric4
;
30 unsigned long ire_nexthop
;
31 unsigned long ire_type
;
32 unsigned long ire_proto
;
33 unsigned long ire_age
;
34 unsigned long ire_mask
;
35 unsigned long ire_metric5
;
36 unsigned long ire_context
;
39 /* Present in headers for Vista+, but there in WinXP/2k3 ntdll */
43 RtlIpv4AddressToStringA(
44 _In_
const struct in_addr
*Addr
,
45 _Out_writes_(16) PSTR S
);
48 static HANDLE TcpFileHandle
;
50 static ULONG IndentationLevel
= 0;
54 dbg_print_physaddr(const unsigned char* addr
, unsigned long addr_len
)
56 static char buffer
[24];
63 dest
+= sprintf(dest
, "%02x", *addr
);
75 indent_printf(const char* format
, ...)
77 ULONG Indent
= IndentationLevel
;
84 va_start(args
, format
);
85 ret
= vprintf(format
, args
);
88 ret
+= IndentationLevel
;
100 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
101 ULONG BufferSize
= sizeof(IFEntry
) + MAX_ADAPTER_DESCRIPTION_LENGTH
+ 1;
104 /* Not valid for other entity types */
105 if (EntityType
!= IF_MIB
)
108 IfEntry
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
109 ok(IfEntry
!= NULL
, "\n");
111 ZeroMemory(&Request
, sizeof(Request
));
112 Request
.ID
.toi_entity
= Id
;
113 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
114 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
115 Request
.ID
.toi_id
= IF_MIB_STATS_ID
;
117 Result
= DeviceIoControl(
119 IOCTL_TCP_QUERY_INFORMATION_EX
,
126 ok(Result
, "DeviceIoControl failed.\n");
129 indent_printf("IF_MIB Statistics:\n");
131 indent_printf("if_index: %lu\n", IfEntry
->if_index
);
132 indent_printf("if_type: %lu\n", IfEntry
->if_type
);
133 indent_printf("if_mtu: %lu\n", IfEntry
->if_mtu
);
134 indent_printf("if_speed: %lu\n", IfEntry
->if_speed
);
135 indent_printf("if_physaddr: %s\n", dbg_print_physaddr(IfEntry
->if_physaddr
, IfEntry
->if_physaddrlen
));
136 indent_printf("if_adminstatus: %lu\n", IfEntry
->if_adminstatus
);
137 indent_printf("if_operstatus: %lu\n", IfEntry
->if_operstatus
);
138 indent_printf("if_lastchange: %lu\n", IfEntry
->if_lastchange
);
139 indent_printf("if_inoctets: %lu\n", IfEntry
->if_inoctets
);
140 indent_printf("if_inucastpkts: %lu\n", IfEntry
->if_inucastpkts
);
141 indent_printf("if_innucastpkts: %lu\n", IfEntry
->if_innucastpkts
);
142 indent_printf("if_indiscards: %lu\n", IfEntry
->if_indiscards
);
143 indent_printf("if_inerrors: %lu\n", IfEntry
->if_inerrors
);
144 indent_printf("if_inunknownprotos: %lu\n", IfEntry
->if_inunknownprotos
);
145 indent_printf("if_outoctets: %lu\n", IfEntry
->if_outoctets
);
146 indent_printf("if_outucastpkts: %lu\n", IfEntry
->if_outucastpkts
);
147 indent_printf("if_outnucastpkts: %lu\n", IfEntry
->if_outnucastpkts
);
148 indent_printf("if_outdiscards: %lu\n", IfEntry
->if_outdiscards
);
149 indent_printf("if_outerrors: %lu\n", IfEntry
->if_outerrors
);
150 indent_printf("if_outqlen: %lu\n", IfEntry
->if_outqlen
);
151 indent_printf("if_descr: %*s\n", IfEntry
->if_descrlen
, IfEntry
->if_descr
);
154 HeapFree(GetProcessHeap(), 0, IfEntry
);
163 IPSNMPInfo IpSnmpInfo
;
164 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
165 ULONG BufferSize
= 0;
168 /* Not valid for other entity types */
169 if (EntityType
!= CL_NL_IP
)
172 ZeroMemory(&IpSnmpInfo
, sizeof(IpSnmpInfo
));
174 ZeroMemory(&Request
, sizeof(Request
));
175 Request
.ID
.toi_entity
= Id
;
176 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
177 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
178 Request
.ID
.toi_id
= IP_MIB_STATS_ID
;
180 Result
= DeviceIoControl(
182 IOCTL_TCP_QUERY_INFORMATION_EX
,
189 ok(Result
, "DeviceIoControl failed.\n");
192 indent_printf("IP_MIB Statistics:\n");
194 indent_printf("ipsi_forwarding: %lu\n", IpSnmpInfo
.ipsi_forwarding
);
195 indent_printf("ipsi_defaultttl: %lu\n", IpSnmpInfo
.ipsi_defaultttl
);
196 indent_printf("ipsi_inreceives: %lu\n", IpSnmpInfo
.ipsi_inreceives
);
197 indent_printf("ipsi_inhdrerrors: %lu\n", IpSnmpInfo
.ipsi_inhdrerrors
);
198 indent_printf("ipsi_inaddrerrors: %lu\n", IpSnmpInfo
.ipsi_inaddrerrors
);
199 indent_printf("ipsi_forwdatagrams: %lu\n", IpSnmpInfo
.ipsi_forwdatagrams
);
200 indent_printf("ipsi_inunknownprotos: %lu\n", IpSnmpInfo
.ipsi_inunknownprotos
);
201 indent_printf("ipsi_indiscards: %lu\n", IpSnmpInfo
.ipsi_indiscards
);
202 indent_printf("ipsi_indelivers: %lu\n", IpSnmpInfo
.ipsi_indelivers
);
203 indent_printf("ipsi_outrequests: %lu\n", IpSnmpInfo
.ipsi_outrequests
);
204 indent_printf("ipsi_routingdiscards: %lu\n", IpSnmpInfo
.ipsi_routingdiscards
);
205 indent_printf("ipsi_outdiscards: %lu\n", IpSnmpInfo
.ipsi_outdiscards
);
206 indent_printf("ipsi_outnoroutes: %lu\n", IpSnmpInfo
.ipsi_outnoroutes
);
207 indent_printf("ipsi_reasmtimeout: %lu\n", IpSnmpInfo
.ipsi_reasmtimeout
);
208 indent_printf("ipsi_reasmreqds: %lu\n", IpSnmpInfo
.ipsi_reasmreqds
);
209 indent_printf("ipsi_reasmoks: %lu\n", IpSnmpInfo
.ipsi_reasmoks
);
210 indent_printf("ipsi_reasmfails: %lu\n", IpSnmpInfo
.ipsi_reasmfails
);
211 indent_printf("ipsi_fragoks: %lu\n", IpSnmpInfo
.ipsi_fragoks
);
212 indent_printf("ipsi_fragfails: %lu\n", IpSnmpInfo
.ipsi_fragfails
);
213 indent_printf("ipsi_fragcreates: %lu\n", IpSnmpInfo
.ipsi_fragcreates
);
214 indent_printf("ipsi_numif: %lu\n", IpSnmpInfo
.ipsi_numif
);
215 indent_printf("ipsi_numaddr: %lu\n", IpSnmpInfo
.ipsi_numaddr
);
216 indent_printf("ipsi_numroutes: %lu\n", IpSnmpInfo
.ipsi_numroutes
);
218 if (IpSnmpInfo
.ipsi_numaddr
!= 0)
220 IPAddrEntry
* AddrEntries
;
223 AddrEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]));
224 ok(AddrEntries
!= NULL
, "\n");
226 ZeroMemory(&Request
, sizeof(Request
));
227 Request
.ID
.toi_entity
= Id
;
228 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
229 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
230 Request
.ID
.toi_id
= IP_MIB_ADDRTABLE_ENTRY_ID
;
232 Result
= DeviceIoControl(
234 IOCTL_TCP_QUERY_INFORMATION_EX
,
238 IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]),
241 ok(Result
, "DeviceIoControl failed.\n");
242 ok_long(BufferSize
, IpSnmpInfo
.ipsi_numaddr
* sizeof(AddrEntries
[0]));
244 for(i
= 0; i
< IpSnmpInfo
.ipsi_numaddr
; i
++)
246 CHAR AddressString
[16];
249 Addr
.S_un
.S_addr
= AddrEntries
[i
].iae_addr
;
250 RtlIpv4AddressToStringA(&Addr
, AddressString
);
252 indent_printf("Address %lu: %s\n", i
, AddressString
);
256 indent_printf("iae_addr: %lx\n", AddrEntries
[i
].iae_addr
);
257 indent_printf("iae_index: %lu\n", AddrEntries
[i
].iae_index
);
258 Addr
.S_un
.S_addr
= AddrEntries
[i
].iae_mask
;
259 RtlIpv4AddressToStringA(&Addr
, AddressString
);
260 indent_printf("iae_mask: %lx (%s)\n", AddrEntries
[i
].iae_mask
, AddressString
);
261 indent_printf("iae_bcastaddr: %lu\n", AddrEntries
[i
].iae_bcastaddr
);
262 indent_printf("iae_reasmsize: %lu\n", AddrEntries
[i
].iae_reasmsize
);
263 indent_printf("iae_context: %u\n", AddrEntries
[i
].iae_context
);
266 IPInterfaceInfo
* InterfaceInfo
;
268 /* Get the interface info */
269 BufferSize
= sizeof(IPInterfaceInfo
) + MAX_PHYSADDR_SIZE
;
270 InterfaceInfo
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
271 ok(InterfaceInfo
!= NULL
, "\n");
273 Request
.ID
.toi_id
= IP_INTFC_INFO_ID
;
274 Request
.Context
[0] = AddrEntries
[i
].iae_addr
;
275 Result
= DeviceIoControl(
277 IOCTL_TCP_QUERY_INFORMATION_EX
,
284 ok(Result
, "DeviceIoControl failed.\n");
286 indent_printf("Interface info:\n");
289 indent_printf("iii_flags: %lu\n", InterfaceInfo
->iii_flags
);
290 indent_printf("iii_mtu : %lu\n", InterfaceInfo
->iii_mtu
);
291 indent_printf("iii_speed: %lu\n", InterfaceInfo
->iii_speed
);
292 indent_printf("iii_physaddr: %s\n", dbg_print_physaddr(InterfaceInfo
->iii_addr
, InterfaceInfo
->iii_addrlength
));
300 HeapFree(GetProcessHeap(), 0, AddrEntries
);
303 /* See for the routes */
304 if (IpSnmpInfo
.ipsi_numroutes
)
306 IPRouteEntry
* RouteEntries
;
309 RouteEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]));
310 ok(RouteEntries
!= NULL
, "\n");
312 ZeroMemory(&Request
, sizeof(Request
));
313 Request
.ID
.toi_entity
= Id
;
314 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
315 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
316 Request
.ID
.toi_id
= IP_MIB_ARPTABLE_ENTRY_ID
;
318 Result
= DeviceIoControl(
320 IOCTL_TCP_QUERY_INFORMATION_EX
,
324 IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]),
327 ok(Result
, "DeviceIoControl failed.\n");
328 ok_long(BufferSize
, IpSnmpInfo
.ipsi_numroutes
* sizeof(RouteEntries
[0]));
330 for (i
= 0; i
< IpSnmpInfo
.ipsi_numroutes
; i
++)
332 CHAR AddressString
[16];
335 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_dest
;
336 RtlIpv4AddressToStringA(&Addr
, AddressString
);
338 indent_printf("Route %lu:\n", i
);
342 indent_printf("ire_dest: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_dest
);
343 indent_printf("ire_index: %lu\n", RouteEntries
[i
].ire_index
);
344 indent_printf("ire_metric1: %#lx\n", RouteEntries
[i
].ire_metric1
);
345 indent_printf("ire_metric2: %#lx\n", RouteEntries
[i
].ire_metric2
);
346 indent_printf("ire_metric3: %#lx\n", RouteEntries
[i
].ire_metric3
);
347 indent_printf("ire_metric4: %#lx\n", RouteEntries
[i
].ire_metric4
);
348 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_nexthop
;
349 RtlIpv4AddressToStringA(&Addr
, AddressString
);
350 indent_printf("ire_nexthop: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_nexthop
);
351 indent_printf("ire_type: %lu\n", RouteEntries
[i
].ire_type
);
352 indent_printf("ire_proto: %lu\n", RouteEntries
[i
].ire_proto
);
353 indent_printf("ire_age: %lu\n", RouteEntries
[i
].ire_age
);
354 Addr
.S_un
.S_addr
= RouteEntries
[i
].ire_mask
;
355 RtlIpv4AddressToStringA(&Addr
, AddressString
);
356 indent_printf("ire_mask: %s (%lx)\n", AddressString
, RouteEntries
[i
].ire_mask
);
357 indent_printf("ire_metric5: %lx\n", RouteEntries
[i
].ire_metric5
);
358 indent_printf("ire_context: %lx\n", RouteEntries
[i
].ire_context
);
367 typedef struct ARPInfo
369 unsigned long ai_numroutes
;
370 unsigned long ai_unknown
;
373 typedef struct ARPEntry
375 unsigned long ae_index
;
376 unsigned long ae_physaddrlen
;
377 unsigned char ae_physaddr
[MAX_PHYSADDR_SIZE
];
378 unsigned long ae_address
;
379 unsigned long ae_unknown
;
389 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
390 ULONG BufferSize
= 0;
393 /* Not valid for other entity types */
394 if (EntityType
!= AT_ARP
)
397 ZeroMemory(&Request
, sizeof(Request
));
398 Request
.ID
.toi_entity
= Id
;
399 Request
.ID
.toi_class
= INFO_CLASS_PROTOCOL
;
400 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
401 Request
.ID
.toi_id
= AT_MIB_ADDRXLAT_INFO_ID
;
403 Result
= DeviceIoControl(
405 IOCTL_TCP_QUERY_INFORMATION_EX
,
412 ok(Result
, "DeviceIoControl failed.\n");
413 ok_long(BufferSize
, sizeof(ArpInfo
));
415 indent_printf("ARP Info:\n");
418 indent_printf("ai_numroutes: %lu\n", ArpInfo
.ai_numroutes
);
419 indent_printf("ai_unknown: %lx\n", ArpInfo
.ai_unknown
);
421 if (ArpInfo
.ai_numroutes
)
423 ARPEntry
* ArpEntries
;
426 Request
.ID
.toi_id
= AT_MIB_ADDRXLAT_ENTRY_ID
;
428 ArpEntries
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]));
429 ok(ArpEntries
!= NULL
, "\n");
431 Result
= DeviceIoControl(
433 IOCTL_TCP_QUERY_INFORMATION_EX
,
437 ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]),
440 ok(Result
, "DeviceIoControl failed.\n");
441 ok_long(BufferSize
, ArpInfo
.ai_numroutes
* sizeof(ArpEntries
[0]));
443 for (i
= 0; i
< ArpInfo
.ai_numroutes
; i
++)
445 CHAR AddressString
[16];
448 Addr
.S_un
.S_addr
= ArpEntries
[i
].ae_address
;
449 RtlIpv4AddressToStringA(&Addr
, AddressString
);
451 indent_printf("ARP Entry %lu:\n", i
);
455 indent_printf("ae_index: %lu\n", ArpEntries
[i
].ae_index
);
456 indent_printf("ae_physaddr: %s\n", dbg_print_physaddr(ArpEntries
[i
].ae_physaddr
, ArpEntries
[i
].ae_physaddrlen
));
457 indent_printf("ae_address: %lx (%s)\n", ArpEntries
[i
].ae_address
, AddressString
);
458 indent_printf("ae_unknown: %lu.\n", ArpEntries
[i
].ae_unknown
);
463 HeapFree(GetProcessHeap(), 0, ArpEntries
);
471 TDIEntityID
* Entities
;
474 ULONG i
, EntityCount
;
475 TCP_REQUEST_QUERY_INFORMATION_EX Request
;
477 /* Open a control channel file for TCP */
478 TcpFileHandle
= CreateFileW(
480 FILE_READ_DATA
| FILE_WRITE_DATA
,
481 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
486 ok(TcpFileHandle
!= INVALID_HANDLE_VALUE
, "CreateFile failed, GLE %lu\n", GetLastError());
490 Result
= DeviceIoControl(
492 IOCTL_TCP_QUERY_INFORMATION_EX
,
499 ok(!Result
, "DeviceIoControl succeeded.\n");
500 ok_long(GetLastError(), ERROR_INVALID_PARAMETER
);
501 ok_long(BufferSize
, 0);
503 ZeroMemory(&Request
, sizeof(Request
));
504 Request
.ID
.toi_entity
.tei_entity
= GENERIC_ENTITY
;
505 Request
.ID
.toi_entity
.tei_instance
= 0;
506 Request
.ID
.toi_class
= INFO_CLASS_GENERIC
;
507 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
508 Request
.ID
.toi_id
= ENTITY_LIST_ID
;
511 Result
= DeviceIoControl(
513 IOCTL_TCP_QUERY_INFORMATION_EX
,
520 ok(!Result
, "DeviceIoControl succeeded.\n");
521 ok_long(GetLastError(), ERROR_INVALID_PARAMETER
);
522 ok_long(BufferSize
, 0);
524 BufferSize
= 4 * sizeof(Entities
[0]);
525 Entities
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, BufferSize
);
526 ok(Entities
!= NULL
, "\n");
530 Result
= DeviceIoControl(
532 IOCTL_TCP_QUERY_INFORMATION_EX
,
543 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
547 Entities
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Entities
, BufferSize
);
548 ok(Entities
!= NULL
, "\n");
551 ok(Result
, "DeviceIoControl failed!\n");
552 EntityCount
= BufferSize
/ sizeof(Entities
[0]);
553 trace("Got %lu entities.\n", EntityCount
);
555 for (i
= 0; i
< EntityCount
; i
++)
560 Request
.ID
.toi_entity
= Entities
[i
];
561 Request
.ID
.toi_class
= INFO_CLASS_GENERIC
;
562 Request
.ID
.toi_type
= INFO_TYPE_PROVIDER
;
563 Request
.ID
.toi_id
= ENTITY_TYPE_ID
;
565 Result
= DeviceIoControl(
567 IOCTL_TCP_QUERY_INFORMATION_EX
,
574 ok(Result
, "DeviceIoControl failed.\n");
576 printf("Entity %lu: %#lx, %#lx, type %#lx\n", i
, Entities
[i
].tei_entity
, Entities
[i
].tei_instance
, EntityType
);
577 test_IF_MIB_STATS(Entities
[i
], EntityType
);
578 test_IP_MIB_STATS(Entities
[i
], EntityType
);
579 test_AT_ARP_STATS(Entities
[i
], EntityType
);
582 HeapFree(GetProcessHeap(), 0, Entities
);
583 CloseHandle(TcpFileHandle
);