040a48088d375f2f858c698f6540acb692c816e4
[reactos.git] / dll / win32 / iphlpapi / ipstats_reactos.c
1 /* Copyright (C) 2003 Art Yerkes
2 * A reimplementation of ifenum.c by Juan Lang
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * This file is implemented on the IOCTL_TCP_QUERY_INFORMATION_EX ioctl on
19 * tcpip.sys
20 */
21
22 #include "iphlpapi_private.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
25
26 #ifndef TCPS_ESTABLISHED
27 # define TCPS_ESTABLISHED TCP_ESTABLISHED
28 #endif
29 #ifndef TCPS_SYN_SENT
30 # define TCPS_SYN_SENT TCP_SYN_SENT
31 #endif
32 #ifndef TCPS_SYN_RECEIVED
33 # define TCPS_SYN_RECEIVED TCP_SYN_RECV
34 #endif
35 #ifndef TCPS_FIN_WAIT_1
36 # define TCPS_FIN_WAIT_1 TCP_FIN_WAIT1
37 #endif
38 #ifndef TCPS_FIN_WAIT_2
39 # define TCPS_FIN_WAIT_2 TCP_FIN_WAIT2
40 #endif
41 #ifndef TCPS_TIME_WAIT
42 # define TCPS_TIME_WAIT TCP_TIME_WAIT
43 #endif
44 #ifndef TCPS_CLOSED
45 # define TCPS_CLOSED TCP_CLOSE
46 #endif
47 #ifndef TCPS_CLOSE_WAIT
48 # define TCPS_CLOSE_WAIT TCP_CLOSE_WAIT
49 #endif
50 #ifndef TCPS_LAST_ACK
51 # define TCPS_LAST_ACK TCP_LAST_ACK
52 #endif
53 #ifndef TCPS_LISTEN
54 # define TCPS_LISTEN TCP_LISTEN
55 #endif
56 #ifndef TCPS_CLOSING
57 # define TCPS_CLOSING TCP_CLOSING
58 #endif
59
60 BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) {
61 return (ent->tei_entity == CL_NL_ENTITY ||
62 ent->tei_entity == CO_NL_ENTITY);
63 }
64
65 NTSTATUS getNthIpEntity( HANDLE tcpFile, DWORD index, TDIEntityID *ent ) {
66 DWORD numEntities = 0;
67 DWORD numRoutes = 0;
68 TDIEntityID *entitySet = 0;
69 NTSTATUS status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
70 int i;
71
72 if( !NT_SUCCESS(status) )
73 return status;
74
75 for( i = 0; i < numEntities; i++ ) {
76 if( isIpEntity( tcpFile, &entitySet[i] ) ) {
77 TRACE("Entity %d is an IP Entity\n", i);
78 if( numRoutes == index ) break;
79 else numRoutes++;
80 }
81 }
82
83 if( numRoutes == index && i < numEntities ) {
84 TRACE("Index %lu is entity #%d - %04x:%08x\n", index, i,
85 entitySet[i].tei_entity, entitySet[i].tei_instance);
86 memcpy( ent, &entitySet[i], sizeof(*ent) );
87 tdiFreeThingSet( entitySet );
88 return STATUS_SUCCESS;
89 } else {
90 tdiFreeThingSet( entitySet );
91 return STATUS_UNSUCCESSFUL;
92 }
93 }
94
95 NTSTATUS tdiGetMibForIpEntity
96 ( HANDLE tcpFile, TDIEntityID *ent, IPSNMPInfo *entry ) {
97 TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT;
98 NTSTATUS status = STATUS_SUCCESS;
99 DWORD returnSize;
100
101 memset( entry, 0, sizeof( *entry ) );
102
103 TRACE("TdiGetMibForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
104 tcpFile, ent->tei_instance);
105
106 req.ID.toi_class = INFO_CLASS_PROTOCOL;
107 req.ID.toi_type = INFO_TYPE_PROVIDER;
108 req.ID.toi_id = IP_MIB_STATS_ID;
109 req.ID.toi_entity = *ent;
110
111 status = DeviceIoControl( tcpFile,
112 IOCTL_TCP_QUERY_INFORMATION_EX,
113 &req,
114 sizeof(req),
115 entry,
116 sizeof(*entry),
117 &returnSize,
118 NULL );
119
120 TRACE("TdiGetMibForIpEntity() => status = 0x%08lx, entry = {\n"
121 " ipsi_forwarding ............ %lu\n"
122 " ipsi_defaultttl ............ %lu\n"
123 " ipsi_inreceives ............ %lu\n"
124 " ipsi_indelivers ............ %lu\n"
125 " ipsi_outrequests ........... %lu\n"
126 " ipsi_routingdiscards ....... %lu\n"
127 " ipsi_outdiscards ........... %lu\n"
128 " ipsi_outnoroutes ........... %lu\n"
129 " ipsi_numif ................. %lu\n"
130 " ipsi_numaddr ............... %lu\n"
131 " ipsi_numroutes ............. %lu\n"
132 "}\n",
133 status,
134 entry->ipsi_forwarding,
135 entry->ipsi_defaultttl,
136 entry->ipsi_inreceives,
137 entry->ipsi_indelivers,
138 entry->ipsi_outrequests,
139 entry->ipsi_routingdiscards,
140 entry->ipsi_outdiscards,
141 entry->ipsi_outnoroutes,
142 entry->ipsi_numif,
143 entry->ipsi_numaddr,
144 entry->ipsi_numroutes);
145
146 return status;
147 }
148
149 NTSTATUS tdiGetRoutesForIpEntity
150 ( HANDLE tcpFile, TDIEntityID *ent, IPRouteEntry **routes, PDWORD numRoutes ) {
151 NTSTATUS status = STATUS_SUCCESS;
152
153 TRACE("TdiGetRoutesForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
154 tcpFile, ent->tei_instance);
155
156 status = tdiGetSetOfThings( tcpFile,
157 INFO_CLASS_PROTOCOL,
158 INFO_TYPE_PROVIDER,
159 IP_MIB_ARPTABLE_ENTRY_ID,
160 CL_NL_ENTITY,
161 ent->tei_instance,
162 0,
163 sizeof(IPRouteEntry),
164 (PVOID *)routes,
165 numRoutes);
166
167 return status;
168 }
169
170 NTSTATUS tdiGetIpAddrsForIpEntity
171 ( HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs, PDWORD numAddrs ) {
172 NTSTATUS status;
173
174 TRACE("TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%x)\n",
175 tcpFile, ent->tei_instance);
176
177 status = tdiGetSetOfThings( tcpFile,
178 INFO_CLASS_PROTOCOL,
179 INFO_TYPE_PROVIDER,
180 IP_MIB_ADDRTABLE_ENTRY_ID,
181 CL_NL_ENTITY,
182 ent->tei_instance,
183 0,
184 sizeof(IPAddrEntry),
185 (PVOID *)addrs,
186 numAddrs );
187
188 return status;
189 }
190
191 DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry)
192 {
193 if (!name)
194 return ERROR_INVALID_PARAMETER;
195 if (!entry)
196 return ERROR_INVALID_PARAMETER;
197
198 return NO_ERROR;
199 }
200
201 DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry)
202 {
203 return ERROR_INVALID_PARAMETER;
204 }
205
206 DWORD getICMPStats(MIB_ICMP *stats)
207 {
208 FILE *fp;
209
210 if (!stats)
211 return ERROR_INVALID_PARAMETER;
212
213 memset(stats, 0, sizeof(MIB_ICMP));
214 /* get most of these stats from /proc/net/snmp, no error if can't */
215 fp = fopen("/proc/net/snmp", "r");
216 if (fp) {
217 const char hdr[] = "Icmp:";
218 char buf[512] = { 0 }, *ptr;
219
220 do {
221 ptr = fgets(buf, sizeof(buf), fp);
222 } while (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1));
223 if (ptr) {
224 /* last line was a header, get another */
225 ptr = fgets(buf, sizeof(buf), fp);
226 if (ptr && strncasecmp(buf, hdr, sizeof(hdr) - 1) == 0) {
227 char *endPtr;
228
229 ptr += sizeof(hdr);
230 if (ptr && *ptr) {
231 stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10);
232 ptr = endPtr;
233 }
234 if (ptr && *ptr) {
235 stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10);
236 ptr = endPtr;
237 }
238 if (ptr && *ptr) {
239 stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
240 ptr = endPtr;
241 }
242 if (ptr && *ptr) {
243 stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
244 ptr = endPtr;
245 }
246 if (ptr && *ptr) {
247 stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
248 ptr = endPtr;
249 }
250 if (ptr && *ptr) {
251 stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
252 ptr = endPtr;
253 }
254 if (ptr && *ptr) {
255 stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10);
256 ptr = endPtr;
257 }
258 if (ptr && *ptr) {
259 stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
260 ptr = endPtr;
261 }
262 if (ptr && *ptr) {
263 stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
264 ptr = endPtr;
265 }
266 if (ptr && *ptr) {
267 stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
268 ptr = endPtr;
269 }
270 if (ptr && *ptr) {
271 stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
272 ptr = endPtr;
273 }
274 if (ptr && *ptr) {
275 stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
276 ptr = endPtr;
277 }
278 if (ptr && *ptr) {
279 stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10);
280 ptr = endPtr;
281 }
282 if (ptr && *ptr) {
283 stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10);
284 ptr = endPtr;
285 }
286 if (ptr && *ptr) {
287 stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10);
288 ptr = endPtr;
289 }
290 if (ptr && *ptr) {
291 stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10);
292 ptr = endPtr;
293 }
294 if (ptr && *ptr) {
295 stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10);
296 ptr = endPtr;
297 }
298 if (ptr && *ptr) {
299 stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10);
300 ptr = endPtr;
301 }
302 if (ptr && *ptr) {
303 stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10);
304 ptr = endPtr;
305 }
306 if (ptr && *ptr) {
307 stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10);
308 ptr = endPtr;
309 }
310 if (ptr && *ptr) {
311 stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10);
312 ptr = endPtr;
313 }
314 if (ptr && *ptr) {
315 stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10);
316 ptr = endPtr;
317 }
318 if (ptr && *ptr) {
319 stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10);
320 ptr = endPtr;
321 }
322 if (ptr && *ptr) {
323 stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10);
324 ptr = endPtr;
325 }
326 }
327 }
328 fclose(fp);
329 }
330 return NO_ERROR;
331 }
332
333 DWORD getIPStats(PMIB_IPSTATS stats, DWORD family)
334 {
335 if (!stats)
336 return ERROR_INVALID_PARAMETER;
337 return NO_ERROR;
338 }
339
340 DWORD getTCPStats(MIB_TCPSTATS *stats, DWORD family)
341 {
342 if (!stats)
343 return ERROR_INVALID_PARAMETER;
344 return NO_ERROR;
345 }
346
347 DWORD getUDPStats(MIB_UDPSTATS *stats, DWORD family)
348 {
349 if (!stats)
350 return ERROR_INVALID_PARAMETER;
351 return NO_ERROR;
352 }
353
354 DWORD getNumRoutes(void)
355 {
356 DWORD numEntities, numRoutes = 0;
357 TDIEntityID *entitySet;
358 HANDLE tcpFile;
359 int i;
360 NTSTATUS status;
361
362 TRACE("called.\n");
363
364 status = openTcpFile( &tcpFile, FILE_READ_DATA );
365 if( !NT_SUCCESS(status) ) {
366 ERR("openTcpFile returned 0x%08lx\n", status);
367 return 0;
368 }
369
370 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
371 if( !NT_SUCCESS(status) ) {
372 ERR("tdiGetEntityIDSet returned 0x%08lx\n", status);
373 closeTcpFile( tcpFile );
374 return 0;
375 }
376
377 for( i = 0; i < numEntities; i++ ) {
378 if( isIpEntity( tcpFile, &entitySet[i] ) ) {
379 IPSNMPInfo isnmp;
380 memset( &isnmp, 0, sizeof( isnmp ) );
381 status = tdiGetMibForIpEntity( tcpFile, &entitySet[i], &isnmp );
382 if( !NT_SUCCESS(status) ) {
383 ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d", status, i);
384 numRoutes = 0;
385 break;
386 }
387 numRoutes += isnmp.ipsi_numroutes;
388 }
389 }
390
391 TRACE("numRoutes = %lu\n", numRoutes);
392
393 tdiFreeThingSet( entitySet );
394 closeTcpFile( tcpFile );
395
396 return numRoutes;
397 }
398
399 VOID HexDump( PCHAR Data, DWORD Len ) {
400 int i;
401
402 for( i = 0; i < Len; i++ ) {
403 if( !(i & 0xf) ) {
404 if( i ) fprintf(stderr,"\n");
405 fprintf(stderr,"%08x:", i);
406 }
407 fprintf( stderr, " %02x", Data[i] & 0xff );
408 }
409 fprintf(stderr,"\n");
410 }
411
412 RouteTable *getRouteTable(void)
413 {
414 RouteTable *out_route_table;
415 DWORD numRoutes = getNumRoutes(), routesAdded = 0;
416 TDIEntityID ent;
417 HANDLE tcpFile;
418 NTSTATUS status = openTcpFile( &tcpFile, FILE_READ_DATA );
419 int i;
420
421 if( !NT_SUCCESS(status) )
422 return 0;
423
424 TRACE("GETTING ROUTE TABLE\n");
425
426 out_route_table = HeapAlloc( GetProcessHeap(), 0,
427 sizeof(RouteTable) +
428 (sizeof(RouteEntry) * (numRoutes - 1)) );
429 if (!out_route_table) {
430 closeTcpFile(tcpFile);
431 return NULL;
432 }
433
434 out_route_table->numRoutes = numRoutes;
435
436 for( i = 0; routesAdded < out_route_table->numRoutes; i++ ) {
437 int j;
438 IPRouteEntry *route_set;
439
440 getNthIpEntity( tcpFile, i, &ent );
441
442 tdiGetRoutesForIpEntity( tcpFile, &ent, &route_set, &numRoutes );
443
444 if( !route_set ) {
445 closeTcpFile( tcpFile );
446 HeapFree( GetProcessHeap(), 0, out_route_table );
447 return 0;
448 }
449
450 TRACE("%lu routes in instance %d\n", numRoutes, i);
451 #if 0
452 HexDump( route_set,
453 sizeof( IPRouteEntry ) *
454 snmpInfo.ipsi_numroutes );
455 #endif
456
457 for( j = 0; j < numRoutes; j++ ) {
458 int routeNum = j + routesAdded;
459 out_route_table->routes[routeNum].dest =
460 route_set[j].ire_dest;
461 out_route_table->routes[routeNum].mask =
462 route_set[j].ire_mask;
463 out_route_table->routes[routeNum].gateway =
464 route_set[j].ire_gw;
465 out_route_table->routes[routeNum].ifIndex =
466 route_set[j].ire_index;
467 out_route_table->routes[routeNum].metric =
468 route_set[j].ire_metric1;
469 }
470
471 if( route_set ) tdiFreeThingSet( route_set );
472
473 routesAdded += numRoutes;
474 }
475
476 closeTcpFile( tcpFile );
477
478 TRACE("status = 0x%08lx, out_route_table = 0x%p\n", status, out_route_table);
479
480 return out_route_table;
481 }
482
483 DWORD getNumArpEntries(void)
484 {
485 DWORD numEntities;
486 TDIEntityID *entitySet = NULL;
487 HANDLE tcpFile;
488 int i, totalNumber = 0;
489 NTSTATUS status;
490 PMIB_IPNETROW IpArpTable = NULL;
491 DWORD returnSize;
492
493 TRACE("called.\n");
494
495 status = openTcpFile( &tcpFile, FILE_READ_DATA );
496 if( !NT_SUCCESS(status) ) {
497 ERR("openTcpFile returned 0x%08lx\n", status);
498 return 0;
499 }
500
501 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
502
503 for( i = 0; i < numEntities; i++ ) {
504 if( isInterface( &entitySet[i] ) &&
505 hasArp( tcpFile, &entitySet[i] ) ) {
506
507 status = tdiGetSetOfThings( tcpFile,
508 INFO_CLASS_PROTOCOL,
509 INFO_TYPE_PROVIDER,
510 IP_MIB_ARPTABLE_ENTRY_ID,
511 AT_ENTITY,
512 entitySet[i].tei_instance,
513 0,
514 sizeof(MIB_IPNETROW),
515 (PVOID *)&IpArpTable,
516 &returnSize );
517
518 if( status == STATUS_SUCCESS ) totalNumber += returnSize;
519 if( IpArpTable ) {
520 tdiFreeThingSet( IpArpTable );
521 IpArpTable = NULL;
522 }
523 }
524 }
525
526 closeTcpFile( tcpFile );
527 if( IpArpTable ) tdiFreeThingSet( IpArpTable );
528 if( entitySet ) tdiFreeThingSet( entitySet );
529 return totalNumber;
530 }
531
532 PMIB_IPNETTABLE getArpTable(void)
533 {
534 DWORD numEntities, returnSize;
535 TDIEntityID *entitySet;
536 HANDLE tcpFile;
537 int i, totalNumber, TmpIdx, CurrIdx = 0;
538 NTSTATUS status;
539 PMIB_IPNETTABLE IpArpTable = NULL;
540 PMIB_IPNETROW AdapterArpTable = NULL;
541
542 TRACE("called.\n");
543
544 totalNumber = getNumArpEntries();
545
546 status = openTcpFile( &tcpFile, FILE_READ_DATA );
547 if( !NT_SUCCESS(status) ) {
548 ERR("openTcpFile returned 0x%08lx\n", status);
549 return 0;
550 }
551
552 IpArpTable = HeapAlloc
553 ( GetProcessHeap(), 0,
554 sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) );
555 if (!IpArpTable) {
556 closeTcpFile(tcpFile);
557 return NULL;
558 }
559
560 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
561
562 for( i = 0; i < numEntities; i++ ) {
563 if( isInterface( &entitySet[i] ) &&
564 hasArp( tcpFile, &entitySet[i] ) ) {
565
566 status = tdiGetSetOfThings( tcpFile,
567 INFO_CLASS_PROTOCOL,
568 INFO_TYPE_PROVIDER,
569 IP_MIB_ARPTABLE_ENTRY_ID,
570 AT_ENTITY,
571 entitySet[i].tei_instance,
572 0,
573 sizeof(MIB_IPNETROW),
574 (PVOID *)&AdapterArpTable,
575 &returnSize );
576
577 if( status == STATUS_SUCCESS ) {
578 for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
579 IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx];
580 tdiFreeThingSet( AdapterArpTable );
581 }
582 }
583 }
584
585 closeTcpFile( tcpFile );
586
587 tdiFreeThingSet( entitySet );
588 IpArpTable->dwNumEntries = CurrIdx;
589
590 return IpArpTable;
591 }
592
593 DWORD getNumUdpEntries(void)
594 {
595 DWORD numEntities;
596 TDIEntityID *entitySet = NULL;
597 HANDLE tcpFile;
598 int i, totalNumber = 0;
599 NTSTATUS status;
600 PMIB_UDPROW IpUdpTable = NULL;
601 DWORD returnSize;
602
603 TRACE("called.\n");
604
605 status = openTcpFile( &tcpFile, FILE_READ_DATA );
606 if( !NT_SUCCESS(status) ) {
607 ERR("openTcpFile returned 0x%08lx\n", status);
608 return 0;
609 }
610
611 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
612
613 for( i = 0; i < numEntities; i++ ) {
614 if( isInterface( &entitySet[i] ) &&
615 hasArp( tcpFile, &entitySet[i] ) ) {
616
617 status = tdiGetSetOfThings( tcpFile,
618 INFO_CLASS_PROTOCOL,
619 INFO_TYPE_PROVIDER,
620 IP_MIB_ARPTABLE_ENTRY_ID,
621 CL_TL_ENTITY,
622 entitySet[i].tei_instance,
623 0,
624 sizeof(MIB_UDPROW),
625 (PVOID *)&IpUdpTable,
626 &returnSize );
627
628 if( status == STATUS_SUCCESS ) totalNumber += returnSize;
629 if( IpUdpTable ) {
630 tdiFreeThingSet( IpUdpTable );
631 IpUdpTable = NULL;
632 }
633 }
634 }
635
636 closeTcpFile( tcpFile );
637 if( IpUdpTable ) tdiFreeThingSet( IpUdpTable );
638 if( entitySet ) tdiFreeThingSet( entitySet );
639 return totalNumber;
640 }
641
642 PMIB_UDPTABLE getUdpTable(void)
643 {
644 DWORD numEntities, returnSize;
645 TDIEntityID *entitySet;
646 HANDLE tcpFile;
647 int i, totalNumber, TmpIdx, CurrIdx = 0;
648 NTSTATUS status;
649 PMIB_UDPTABLE IpUdpTable = NULL;
650 PMIB_UDPROW AdapterUdpTable = NULL;
651
652 TRACE("called.\n");
653
654 totalNumber = getNumTcpEntries();
655
656 status = openTcpFile( &tcpFile, FILE_READ_DATA );
657 if( !NT_SUCCESS(status) ) {
658 ERR("openTcpFile returned 0x%08lx\n", status);
659 return 0;
660 }
661
662 IpUdpTable = HeapAlloc
663 ( GetProcessHeap(), 0,
664 sizeof(DWORD) + (sizeof(MIB_UDPROW) * totalNumber) );
665 if (!IpUdpTable) {
666 closeTcpFile(tcpFile);
667 return NULL;
668 }
669
670 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
671
672 for( i = 0; i < numEntities; i++ ) {
673 if( isInterface( &entitySet[i] ) &&
674 hasArp( tcpFile, &entitySet[i] ) ) {
675
676 status = tdiGetSetOfThings( tcpFile,
677 INFO_CLASS_PROTOCOL,
678 INFO_TYPE_PROVIDER,
679 IP_MIB_ARPTABLE_ENTRY_ID,
680 CL_TL_ENTITY,
681 entitySet[i].tei_instance,
682 0,
683 sizeof(MIB_UDPROW),
684 (PVOID *)&AdapterUdpTable,
685 &returnSize );
686
687 if( status == STATUS_SUCCESS ) {
688 for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
689 IpUdpTable->table[CurrIdx] = AdapterUdpTable[TmpIdx];
690 tdiFreeThingSet( AdapterUdpTable );
691 }
692 }
693 }
694
695 closeTcpFile( tcpFile );
696
697 tdiFreeThingSet( entitySet );
698 IpUdpTable->dwNumEntries = CurrIdx;
699
700 return IpUdpTable;
701 }
702
703 DWORD getNumTcpEntries(void)
704 {
705 DWORD numEntities;
706 TDIEntityID *entitySet = NULL;
707 HANDLE tcpFile;
708 int i, totalNumber = 0;
709 NTSTATUS status;
710 PMIB_TCPROW IpTcpTable = NULL;
711 DWORD returnSize;
712
713 TRACE("called.\n");
714
715 status = openTcpFile( &tcpFile, FILE_READ_DATA );
716 if( !NT_SUCCESS(status) ) {
717 ERR("openTcpFile returned 0x%08lx\n", status);
718 return 0;
719 }
720
721 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
722
723 for( i = 0; i < numEntities; i++ ) {
724 if( isInterface( &entitySet[i] ) &&
725 hasArp( tcpFile, &entitySet[i] ) ) {
726
727 status = tdiGetSetOfThings( tcpFile,
728 INFO_CLASS_PROTOCOL,
729 INFO_TYPE_PROVIDER,
730 IP_MIB_ARPTABLE_ENTRY_ID,
731 CO_TL_ENTITY,
732 entitySet[i].tei_instance,
733 0,
734 sizeof(MIB_TCPROW),
735 (PVOID *)&IpTcpTable,
736 &returnSize );
737
738 if( status == STATUS_SUCCESS ) totalNumber += returnSize;
739 if( IpTcpTable ) {
740 tdiFreeThingSet( IpTcpTable );
741 IpTcpTable = NULL;
742 }
743 }
744 }
745
746 closeTcpFile( tcpFile );
747 if( IpTcpTable ) tdiFreeThingSet( IpTcpTable );
748 if( entitySet ) tdiFreeThingSet( entitySet );
749 return totalNumber;
750 }
751
752 PMIB_TCPTABLE getTcpTable(void)
753 {
754 DWORD numEntities, returnSize;
755 TDIEntityID *entitySet;
756 HANDLE tcpFile;
757 int i, totalNumber, TmpIdx, CurrIdx = 0;
758 NTSTATUS status;
759 PMIB_TCPTABLE IpTcpTable = NULL;
760 PMIB_TCPROW AdapterTcpTable = NULL;
761
762 TRACE("called.\n");
763
764 totalNumber = getNumTcpEntries();
765
766 status = openTcpFile( &tcpFile, FILE_READ_DATA );
767 if( !NT_SUCCESS(status) ) {
768 ERR("openTcpFile returned 0x%08lx\n", status);
769 return 0;
770 }
771
772 IpTcpTable = HeapAlloc
773 ( GetProcessHeap(), 0,
774 sizeof(DWORD) + (sizeof(MIB_TCPROW) * totalNumber) );
775 if (!IpTcpTable) {
776 closeTcpFile(tcpFile);
777 return NULL;
778 }
779
780 status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );
781
782 for( i = 0; i < numEntities; i++ ) {
783 if( isInterface( &entitySet[i] ) &&
784 hasArp( tcpFile, &entitySet[i] ) ) {
785
786 status = tdiGetSetOfThings( tcpFile,
787 INFO_CLASS_PROTOCOL,
788 INFO_TYPE_PROVIDER,
789 IP_MIB_ARPTABLE_ENTRY_ID,
790 CO_TL_ENTITY,
791 entitySet[i].tei_instance,
792 0,
793 sizeof(MIB_TCPROW),
794 (PVOID *)&AdapterTcpTable,
795 &returnSize );
796
797 if( status == STATUS_SUCCESS ) {
798 for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
799 IpTcpTable->table[CurrIdx] = AdapterTcpTable[TmpIdx];
800 tdiFreeThingSet( AdapterTcpTable );
801 }
802 }
803 }
804
805 closeTcpFile( tcpFile );
806
807 tdiFreeThingSet( entitySet );
808 IpTcpTable->dwNumEntries = CurrIdx;
809
810 return IpTcpTable;
811 }