Reactos
at master 937 lines 28 kB view raw
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 24WINE_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 60BOOL isIpEntity( HANDLE tcpFile, TDIEntityID *ent ) { 61 return (ent->tei_entity == CL_NL_ENTITY || 62 ent->tei_entity == CO_NL_ENTITY); 63} 64 65NTSTATUS 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 95static NTSTATUS 96tdiGetMibForIpEntity( 97 _In_ HANDLE tcpFile, 98 _In_ TDIEntityID *ent, 99 _Out_ MIB_IPSTATS *entry) 100{ 101 TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; 102 NTSTATUS Status; 103 DWORD returnSize; 104 105 ZeroMemory(entry, sizeof(*entry)); 106 107 TRACE("TdiGetMibForIpEntity(tcpFile 0x%p, entityId 0x%x)\n", 108 tcpFile, ent->tei_instance); 109 110 req.ID.toi_class = INFO_CLASS_PROTOCOL; 111 req.ID.toi_type = INFO_TYPE_PROVIDER; 112 req.ID.toi_id = IP_MIB_STATS_ID; 113 req.ID.toi_entity = *ent; 114 115 Status = DeviceIoControl(tcpFile, 116 IOCTL_TCP_QUERY_INFORMATION_EX, 117 &req, 118 sizeof(req), 119 entry, 120 sizeof(*entry), 121 &returnSize, 122 NULL); 123 124 TRACE("TdiGetMibForIpEntity() => status = 0x%08lx, entry = {\n" 125 " ipsi_forwarding ............ %lu\n" 126 " ipsi_defaultttl ............ %lu\n" 127 " ipsi_inreceives ............ %lu\n" 128 " ipsi_indelivers ............ %lu\n" 129 " ipsi_outrequests ........... %lu\n" 130 " ipsi_routingdiscards ....... %lu\n" 131 " ipsi_outdiscards ........... %lu\n" 132 " ipsi_outnoroutes ........... %lu\n" 133 " ipsi_numif ................. %lu\n" 134 " ipsi_numaddr ............... %lu\n" 135 " ipsi_numroutes ............. %lu\n" 136 "}\n", 137 Status, 138 entry->dwForwarding, 139 entry->dwDefaultTTL, 140 entry->dwInReceives, 141 entry->dwInDelivers, 142 entry->dwOutRequests, 143 entry->dwRoutingDiscards, 144 entry->dwOutDiscards, 145 entry->dwOutNoRoutes, 146 entry->dwNumIf, 147 entry->dwNumAddr, 148 entry->dwNumRoutes); 149 150 return Status; 151} 152 153static NTSTATUS 154tdiGetMibForTcpEntity( 155 _In_ HANDLE tcpFile, 156 _In_ TDIEntityID *ent, 157 _Out_ MIB_TCPSTATS *entry) 158{ 159 TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; 160 NTSTATUS Status; 161 DWORD returnSize; 162 163 ZeroMemory(entry, sizeof(*entry)); 164 165 TRACE("TdiGetMibForTcpEntity(tcpFile 0x%p, entityId 0x%x)\n", 166 tcpFile, ent->tei_instance); 167 168 req.ID.toi_class = INFO_CLASS_PROTOCOL; 169 req.ID.toi_type = INFO_TYPE_PROVIDER; 170 req.ID.toi_id = TCP_MIB_STAT_ID; 171 req.ID.toi_entity = *ent; 172 173 Status = DeviceIoControl(tcpFile, 174 IOCTL_TCP_QUERY_INFORMATION_EX, 175 &req, 176 sizeof(req), 177 entry, 178 sizeof(*entry), 179 &returnSize, 180 NULL); 181 182 TRACE("TdiGetMibForTcpEntity() => status = 0x%08lx, entry = {\n" 183 " dwInSegs ............. %lu\n" 184 " dwOutSegs ............ %lu\n" 185 " dwNumConns ........... %lu\n" 186 "}\n", 187 Status, 188 entry->dwInSegs, 189 entry->dwOutSegs, 190 entry->dwNumConns); 191 192 return Status; 193} 194 195static NTSTATUS 196tdiGetMibForUdpEntity( 197 _In_ HANDLE tcpFile, 198 _In_ TDIEntityID *ent, 199 _Out_ MIB_UDPSTATS *entry) 200{ 201 TCP_REQUEST_QUERY_INFORMATION_EX req = TCP_REQUEST_QUERY_INFORMATION_INIT; 202 NTSTATUS Status; 203 DWORD returnSize; 204 205 ZeroMemory(entry, sizeof(*entry)); 206 207 TRACE("TdiGetMibForUdpEntity(tcpFile 0x%p, entityId 0x%x)\n", 208 tcpFile, ent->tei_instance); 209 210 req.ID.toi_class = INFO_CLASS_PROTOCOL; 211 req.ID.toi_type = INFO_TYPE_PROVIDER; 212 req.ID.toi_id = UDP_MIB_STAT_ID; 213 req.ID.toi_entity = *ent; 214 215 Status = DeviceIoControl(tcpFile, 216 IOCTL_TCP_QUERY_INFORMATION_EX, 217 &req, 218 sizeof(req), 219 entry, 220 sizeof(*entry), 221 &returnSize, 222 NULL); 223 224 TRACE("TdiGetMibForUdpEntity() => status = 0x%08lx, entry = {\n" 225 " dwInDatagrams ....... %lu\n" 226 " dwOutDatagrams ...... %lu\n" 227 " dwNumAddrs .......... %lu\n" 228 "}\n", 229 Status, 230 entry->dwInDatagrams, 231 entry->dwOutDatagrams, 232 entry->dwNumAddrs); 233 234 return Status; 235} 236 237NTSTATUS tdiGetRoutesForIpEntity 238( HANDLE tcpFile, TDIEntityID *ent, IPRouteEntry **routes, PDWORD numRoutes ) { 239 NTSTATUS status = STATUS_SUCCESS; 240 241 TRACE("TdiGetRoutesForIpEntity(tcpFile 0x%p, entityId 0x%x)\n", 242 tcpFile, ent->tei_instance); 243 244 status = tdiGetSetOfThings(tcpFile, 245 INFO_CLASS_PROTOCOL, 246 INFO_TYPE_PROVIDER, 247 IP_MIB_ARPTABLE_ENTRY_ID, 248 CL_NL_ENTITY, 249 ent->tei_instance, 250 0, 251 sizeof(IPRouteEntry), 252 (PVOID *)routes, 253 numRoutes); 254 255 return status; 256} 257 258NTSTATUS tdiGetIpAddrsForIpEntity 259( HANDLE tcpFile, TDIEntityID *ent, IPAddrEntry **addrs, PDWORD numAddrs ) { 260 NTSTATUS status; 261 262 TRACE("TdiGetIpAddrsForIpEntity(tcpFile 0x%p, entityId 0x%x)\n", 263 tcpFile, ent->tei_instance); 264 265 status = tdiGetSetOfThings(tcpFile, 266 INFO_CLASS_PROTOCOL, 267 INFO_TYPE_PROVIDER, 268 IP_MIB_ADDRTABLE_ENTRY_ID, 269 CL_NL_ENTITY, 270 ent->tei_instance, 271 0, 272 sizeof(IPAddrEntry), 273 (PVOID *)addrs, 274 numAddrs); 275 276 return status; 277} 278 279DWORD getInterfaceStatsByName(const char *name, PMIB_IFROW entry) 280{ 281 if (!name) 282 return ERROR_INVALID_PARAMETER; 283 if (!entry) 284 return ERROR_INVALID_PARAMETER; 285 286 return NO_ERROR; 287} 288 289DWORD getInterfaceStatsByIndex(DWORD index, PMIB_IFROW entry) 290{ 291 return ERROR_INVALID_PARAMETER; 292} 293 294DWORD getICMPStats(MIB_ICMP *stats) 295{ 296 FILE *fp; 297 298 if (!stats) 299 return ERROR_INVALID_PARAMETER; 300 301 memset(stats, 0, sizeof(MIB_ICMP)); 302 /* get most of these stats from /proc/net/snmp, no error if can't */ 303 fp = fopen("/proc/net/snmp", "r"); 304 if (fp) { 305 const char hdr[] = "Icmp:"; 306 char buf[512] = { 0 }, *ptr; 307 308 do { 309 ptr = fgets(buf, sizeof(buf), fp); 310 } while (ptr && _strnicmp(buf, hdr, sizeof(hdr) - 1)); 311 if (ptr) { 312 /* last line was a header, get another */ 313 ptr = fgets(buf, sizeof(buf), fp); 314 if (ptr && _strnicmp(buf, hdr, sizeof(hdr) - 1) == 0) { 315 char *endPtr; 316 317 ptr += sizeof(hdr); 318 if (ptr && *ptr) { 319 stats->stats.icmpInStats.dwMsgs = strtoul(ptr, &endPtr, 10); 320 ptr = endPtr; 321 } 322 if (ptr && *ptr) { 323 stats->stats.icmpInStats.dwErrors = strtoul(ptr, &endPtr, 10); 324 ptr = endPtr; 325 } 326 if (ptr && *ptr) { 327 stats->stats.icmpInStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10); 328 ptr = endPtr; 329 } 330 if (ptr && *ptr) { 331 stats->stats.icmpInStats.dwTimeExcds = strtoul(ptr, &endPtr, 10); 332 ptr = endPtr; 333 } 334 if (ptr && *ptr) { 335 stats->stats.icmpInStats.dwParmProbs = strtoul(ptr, &endPtr, 10); 336 ptr = endPtr; 337 } 338 if (ptr && *ptr) { 339 stats->stats.icmpInStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10); 340 ptr = endPtr; 341 } 342 if (ptr && *ptr) { 343 stats->stats.icmpInStats.dwRedirects = strtoul(ptr, &endPtr, 10); 344 ptr = endPtr; 345 } 346 if (ptr && *ptr) { 347 stats->stats.icmpInStats.dwEchoReps = strtoul(ptr, &endPtr, 10); 348 ptr = endPtr; 349 } 350 if (ptr && *ptr) { 351 stats->stats.icmpInStats.dwTimestamps = strtoul(ptr, &endPtr, 10); 352 ptr = endPtr; 353 } 354 if (ptr && *ptr) { 355 stats->stats.icmpInStats.dwTimestampReps = strtoul(ptr, &endPtr, 10); 356 ptr = endPtr; 357 } 358 if (ptr && *ptr) { 359 stats->stats.icmpInStats.dwAddrMasks = strtoul(ptr, &endPtr, 10); 360 ptr = endPtr; 361 } 362 if (ptr && *ptr) { 363 stats->stats.icmpInStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10); 364 ptr = endPtr; 365 } 366 if (ptr && *ptr) { 367 stats->stats.icmpOutStats.dwMsgs = strtoul(ptr, &endPtr, 10); 368 ptr = endPtr; 369 } 370 if (ptr && *ptr) { 371 stats->stats.icmpOutStats.dwErrors = strtoul(ptr, &endPtr, 10); 372 ptr = endPtr; 373 } 374 if (ptr && *ptr) { 375 stats->stats.icmpOutStats.dwDestUnreachs = strtoul(ptr, &endPtr, 10); 376 ptr = endPtr; 377 } 378 if (ptr && *ptr) { 379 stats->stats.icmpOutStats.dwTimeExcds = strtoul(ptr, &endPtr, 10); 380 ptr = endPtr; 381 } 382 if (ptr && *ptr) { 383 stats->stats.icmpOutStats.dwParmProbs = strtoul(ptr, &endPtr, 10); 384 ptr = endPtr; 385 } 386 if (ptr && *ptr) { 387 stats->stats.icmpOutStats.dwSrcQuenchs = strtoul(ptr, &endPtr, 10); 388 ptr = endPtr; 389 } 390 if (ptr && *ptr) { 391 stats->stats.icmpOutStats.dwRedirects = strtoul(ptr, &endPtr, 10); 392 ptr = endPtr; 393 } 394 if (ptr && *ptr) { 395 stats->stats.icmpOutStats.dwEchoReps = strtoul(ptr, &endPtr, 10); 396 ptr = endPtr; 397 } 398 if (ptr && *ptr) { 399 stats->stats.icmpOutStats.dwTimestamps = strtoul(ptr, &endPtr, 10); 400 ptr = endPtr; 401 } 402 if (ptr && *ptr) { 403 stats->stats.icmpOutStats.dwTimestampReps = strtoul(ptr, &endPtr, 10); 404 ptr = endPtr; 405 } 406 if (ptr && *ptr) { 407 stats->stats.icmpOutStats.dwAddrMasks = strtoul(ptr, &endPtr, 10); 408 ptr = endPtr; 409 } 410 if (ptr && *ptr) { 411 stats->stats.icmpOutStats.dwAddrMaskReps = strtoul(ptr, &endPtr, 10); 412 ptr = endPtr; 413 } 414 } 415 } 416 fclose(fp); 417 } 418 return NO_ERROR; 419} 420 421DWORD getIPStats( 422 _In_ HANDLE TcpFile, 423 _Out_ PMIB_IPSTATS pStats) 424{ 425 TDIEntityID ent; 426 NTSTATUS Status; 427 428 ent.tei_entity = CL_NL_ENTITY; 429 ent.tei_instance = 0; 430 431 Status = tdiGetMibForIpEntity(TcpFile, &ent, pStats); 432 433 if (!NT_SUCCESS(Status)) 434 return RtlNtStatusToDosError(Status); 435 436 return NO_ERROR; 437} 438 439DWORD getTCPStats( 440 _In_ HANDLE TcpFile, 441 _Out_ MIB_TCPSTATS *pStats) 442{ 443 TDIEntityID ent; 444 NTSTATUS Status; 445 446 ent.tei_entity = CO_TL_ENTITY; 447 ent.tei_instance = 0; 448 449 Status = tdiGetMibForTcpEntity(TcpFile, &ent, pStats); 450 451 if (!NT_SUCCESS(Status)) 452 return RtlNtStatusToDosError(Status); 453 454 return NO_ERROR; 455} 456 457DWORD getUDPStats( 458 _In_ HANDLE TcpFile, 459 _Out_ MIB_UDPSTATS *pStats) 460{ 461 TDIEntityID ent; 462 NTSTATUS Status; 463 464 ent.tei_entity = CL_TL_ENTITY; 465 ent.tei_instance = 0; 466 467 Status = tdiGetMibForUdpEntity(TcpFile, &ent, pStats); 468 469 if (!NT_SUCCESS(Status)) 470 return RtlNtStatusToDosError(Status); 471 472 return NO_ERROR; 473} 474 475DWORD getNumRoutes(void) 476{ 477 DWORD numEntities, numRoutes = 0; 478 TDIEntityID *entitySet; 479 HANDLE tcpFile; 480 int i; 481 NTSTATUS status; 482 483 TRACE("called.\n"); 484 485 status = openTcpFile(&tcpFile, FILE_READ_DATA); 486 if (!NT_SUCCESS(status)) 487 { 488 ERR("openTcpFile returned 0x%08lx\n", status); 489 return 0; 490 } 491 492 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 493 if (!NT_SUCCESS(status)) { 494 ERR("tdiGetEntityIDSet returned 0x%08lx\n", status); 495 closeTcpFile( tcpFile ); 496 return 0; 497 } 498 499 for (i = 0; i < numEntities; i++) { 500 if (isIpEntity(tcpFile, &entitySet[i])) { 501 MIB_IPSTATS ipstats; 502 memset(&ipstats, 0, sizeof(ipstats)); 503 status = tdiGetMibForIpEntity(tcpFile, &entitySet[i], &ipstats); 504 if (!NT_SUCCESS(status)) { 505 ERR("tdiGetMibForIpEntity returned 0x%08lx, for i = %d\n", status, i); 506 numRoutes = 0; 507 break; 508 } 509 numRoutes += ipstats.dwNumRoutes; 510 } 511 } 512 513 TRACE("numRoutes = %lu\n", numRoutes); 514 515 tdiFreeThingSet(entitySet); 516 closeTcpFile(tcpFile); 517 518 return numRoutes; 519} 520 521VOID HexDump( PCHAR Data, DWORD Len ) { 522 int i; 523 524 for( i = 0; i < Len; i++ ) { 525 if( !(i & 0xf) ) { 526 if( i ) fprintf(stderr,"\n"); 527 fprintf(stderr,"%08x:", i); 528 } 529 fprintf( stderr, " %02x", Data[i] & 0xff ); 530 } 531 fprintf(stderr,"\n"); 532} 533 534RouteTable *getRouteTable(void) 535{ 536 RouteTable *out_route_table; 537 DWORD numRoutes = getNumRoutes(), routesAdded = 0; 538 TDIEntityID ent; 539 HANDLE tcpFile; 540 NTSTATUS status = openTcpFile(&tcpFile, FILE_READ_DATA); 541 int i; 542 543 if (!NT_SUCCESS(status)) 544 return 0; 545 546 TRACE("GETTING ROUTE TABLE\n"); 547 548 out_route_table = HeapAlloc(GetProcessHeap(), 0, 549 sizeof(RouteTable) + 550 (sizeof(RouteEntry) * (numRoutes - 1))); 551 if (!out_route_table) { 552 closeTcpFile(tcpFile); 553 return NULL; 554 } 555 556 out_route_table->numRoutes = numRoutes; 557 558 for (i = 0; routesAdded < out_route_table->numRoutes; i++) { 559 int j; 560 IPRouteEntry *route_set; 561 562 getNthIpEntity(tcpFile, i, &ent); 563 564 tdiGetRoutesForIpEntity(tcpFile, &ent, &route_set, &numRoutes); 565 if (!route_set) { 566 closeTcpFile(tcpFile); 567 HeapFree(GetProcessHeap(), 0, out_route_table); 568 return 0; 569 } 570 571 TRACE("%lu routes in instance %d\n", numRoutes, i); 572#if 0 573 HexDump(route_set, 574 sizeof(IPRouteEntry) * 575 snmpInfo.ipsi_numroutes); 576#endif 577 578 for (j = 0; j < numRoutes; j++) { 579 int routeNum = j + routesAdded; 580 out_route_table->routes[routeNum].dest = 581 route_set[j].ire_dest; 582 out_route_table->routes[routeNum].mask = 583 route_set[j].ire_mask; 584 out_route_table->routes[routeNum].gateway = 585 route_set[j].ire_gw; 586 out_route_table->routes[routeNum].ifIndex = 587 route_set[j].ire_index; 588 out_route_table->routes[routeNum].metric = 589 route_set[j].ire_metric1; 590 } 591 592 if (route_set) tdiFreeThingSet(route_set); 593 594 routesAdded += numRoutes; 595 } 596 597 closeTcpFile(tcpFile); 598 TRACE("status = 0x%08lx, out_route_table = 0x%p\n", status, out_route_table); 599 return out_route_table; 600} 601 602DWORD getNumArpEntries(void) 603{ 604 DWORD numEntities; 605 TDIEntityID *entitySet = NULL; 606 HANDLE tcpFile; 607 int i, totalNumber = 0; 608 NTSTATUS status; 609 PMIB_IPNETROW IpArpTable = NULL; 610 DWORD returnSize; 611 612 TRACE("called.\n"); 613 614 status = openTcpFile(&tcpFile, FILE_READ_DATA); 615 if (!NT_SUCCESS(status)) 616 { 617 ERR("openTcpFile returned 0x%08lx\n", status); 618 return 0; 619 } 620 621 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 622 623 for (i = 0; i < numEntities; i++) { 624 if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i])) 625 { 626 status = tdiGetSetOfThings(tcpFile, 627 INFO_CLASS_PROTOCOL, 628 INFO_TYPE_PROVIDER, 629 IP_MIB_ARPTABLE_ENTRY_ID, 630 AT_ENTITY, 631 entitySet[i].tei_instance, 632 0, 633 sizeof(MIB_IPNETROW), 634 (PVOID *)&IpArpTable, 635 &returnSize); 636 637 if (status == STATUS_SUCCESS) totalNumber += returnSize; 638 if (IpArpTable) { 639 tdiFreeThingSet(IpArpTable); 640 IpArpTable = NULL; 641 } 642 } 643 } 644 645 closeTcpFile(tcpFile); 646 if (entitySet) tdiFreeThingSet(entitySet); 647 return totalNumber; 648} 649 650PMIB_IPNETTABLE getArpTable(void) 651{ 652 DWORD numEntities, returnSize; 653 TDIEntityID *entitySet; 654 HANDLE tcpFile; 655 int i, totalNumber, TmpIdx, CurrIdx = 0; 656 NTSTATUS status; 657 PMIB_IPNETTABLE IpArpTable = NULL; 658 PMIB_IPNETROW AdapterArpTable = NULL; 659 660 TRACE("called.\n"); 661 662 totalNumber = getNumArpEntries(); 663 664 status = openTcpFile(&tcpFile, FILE_READ_DATA); 665 if (!NT_SUCCESS(status)) 666 { 667 ERR("openTcpFile returned 0x%08lx\n", status); 668 return 0; 669 } 670 671 IpArpTable = HeapAlloc(GetProcessHeap(), 0, 672 sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber)); 673 if (!IpArpTable) { 674 closeTcpFile(tcpFile); 675 return NULL; 676 } 677 678 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 679 680 for (i = 0; i < numEntities; i++) { 681 if (isInterface(&entitySet[i]) && hasArp(tcpFile, &entitySet[i])) 682 { 683 status = tdiGetSetOfThings(tcpFile, 684 INFO_CLASS_PROTOCOL, 685 INFO_TYPE_PROVIDER, 686 IP_MIB_ARPTABLE_ENTRY_ID, 687 AT_ENTITY, 688 entitySet[i].tei_instance, 689 0, 690 sizeof(MIB_IPNETROW), 691 (PVOID *)&AdapterArpTable, 692 &returnSize); 693 694 if (status == STATUS_SUCCESS) { 695 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++) 696 IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx]; 697 tdiFreeThingSet(AdapterArpTable); 698 } 699 } 700 } 701 702 closeTcpFile(tcpFile); 703 tdiFreeThingSet(entitySet); 704 IpArpTable->dwNumEntries = CurrIdx; 705 return IpArpTable; 706} 707 708struct _TABLE_CALL 709{ 710 DWORD TOIID; 711 SIZE_T UdpSize; 712 SIZE_T TcpSize; 713 SIZE_T UdpOffset; 714 SIZE_T TcpOffset; 715} UdpTcpTableCall[] = { 716 {IP_MIB_ARPTABLE_ENTRY_ID, sizeof(MIB_UDPROW), sizeof(MIB_TCPROW), FIELD_OFFSET(MIB_UDPTABLE, table), FIELD_OFFSET(MIB_TCPTABLE, table)}, 717 {IP_MIB_ADDRTABLE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_PID), sizeof(MIB_TCPROW_OWNER_PID), FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table)}, 718 {IP_SPECIFIC_MODULE_ENTRY_ID, sizeof(MIB_UDPROW_OWNER_MODULE), sizeof(MIB_TCPROW_OWNER_MODULE), FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table), FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table)}, 719}; 720 721#define Add2Ptr(PTR, INC) (PVOID)((ULONG_PTR)(PTR) + (INC)) 722 723DWORD getNumUdpEntries(void) 724{ 725 DWORD numEntities; 726 TDIEntityID *entitySet = NULL; 727 HANDLE tcpFile; 728 int i, totalNumber = 0; 729 NTSTATUS status; 730 PMIB_UDPROW IpUdpTable = NULL; 731 DWORD returnSize; 732 733 TRACE("called.\n"); 734 735 status = openTcpFile(&tcpFile, FILE_READ_DATA); 736 if (!NT_SUCCESS(status)) 737 { 738 ERR("openTcpFile returned 0x%08lx\n", status); 739 return 0; 740 } 741 742 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 743 744 for (i = 0; i < numEntities; i++) { 745 if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i])) 746 { 747 status = tdiGetSetOfThings(tcpFile, 748 INFO_CLASS_PROTOCOL, 749 INFO_TYPE_PROVIDER, 750 IP_MIB_ARPTABLE_ENTRY_ID, 751 CL_TL_ENTITY, 752 entitySet[i].tei_instance, 753 0, 754 sizeof(MIB_UDPROW), 755 (PVOID *)&IpUdpTable, 756 &returnSize); 757 758 if (status == STATUS_SUCCESS) totalNumber += returnSize; 759 if (IpUdpTable) { 760 tdiFreeThingSet(IpUdpTable); 761 IpUdpTable = NULL; 762 } 763 } 764 } 765 766 closeTcpFile(tcpFile); 767 if (entitySet) tdiFreeThingSet(entitySet); 768 return totalNumber; 769} 770 771PVOID getUdpTable(CLASS_TABLE Class) 772{ 773 DWORD numEntities, returnSize; 774 TDIEntityID *entitySet; 775 HANDLE tcpFile; 776 int i, totalNumber, TmpIdx, CurrIdx = 0; 777 NTSTATUS status; 778 PMIB_UDPTABLE IpUdpTable = NULL; 779 PVOID AdapterUdpTable = NULL; 780 781 TRACE("called.\n"); 782 783 totalNumber = getNumUdpEntries(); 784 785 status = openTcpFile(&tcpFile, FILE_READ_DATA); 786 if (!NT_SUCCESS(status)) 787 { 788 ERR("openTcpFile returned 0x%08lx\n", status); 789 return 0; 790 } 791 792 IpUdpTable = HeapAlloc(GetProcessHeap(), 0, 793 UdpTcpTableCall[Class].UdpOffset + (UdpTcpTableCall[Class].UdpSize * totalNumber)); 794 if (!IpUdpTable) { 795 closeTcpFile(tcpFile); 796 return NULL; 797 } 798 799 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 800 801 for (i = 0; i < numEntities; i++) { 802 if (entitySet[i].tei_entity == CL_TL_ENTITY && hasArp(tcpFile, &entitySet[i])) 803 { 804 status = tdiGetSetOfThings(tcpFile, 805 INFO_CLASS_PROTOCOL, 806 INFO_TYPE_PROVIDER, 807 UdpTcpTableCall[Class].TOIID, 808 CL_TL_ENTITY, 809 entitySet[i].tei_instance, 810 0, 811 UdpTcpTableCall[Class].UdpSize, 812 &AdapterUdpTable, 813 &returnSize); 814 815 if (status == STATUS_SUCCESS) { 816 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++) 817 CopyMemory(Add2Ptr(IpUdpTable, UdpTcpTableCall[Class].UdpOffset + UdpTcpTableCall[Class].UdpSize * CurrIdx), 818 Add2Ptr(AdapterUdpTable, UdpTcpTableCall[Class].UdpSize * TmpIdx), 819 UdpTcpTableCall[Class].UdpSize); 820 tdiFreeThingSet(AdapterUdpTable); 821 } 822 } 823 } 824 825 closeTcpFile(tcpFile); 826 tdiFreeThingSet(entitySet); 827 IpUdpTable->dwNumEntries = CurrIdx; 828 return IpUdpTable; 829} 830 831DWORD getNumTcpEntries(void) 832{ 833 DWORD numEntities; 834 TDIEntityID *entitySet = NULL; 835 HANDLE tcpFile; 836 int i, totalNumber = 0; 837 NTSTATUS status; 838 PMIB_TCPROW IpTcpTable = NULL; 839 DWORD returnSize; 840 841 TRACE("called.\n"); 842 843 status = openTcpFile(&tcpFile, FILE_READ_DATA); 844 if (!NT_SUCCESS(status)) 845 { 846 ERR("openTcpFile returned 0x%08lx\n", status); 847 return 0; 848 } 849 850 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 851 852 for (i = 0; i < numEntities; i++) { 853 if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i])) 854 { 855 status = tdiGetSetOfThings(tcpFile, 856 INFO_CLASS_PROTOCOL, 857 INFO_TYPE_PROVIDER, 858 IP_MIB_ARPTABLE_ENTRY_ID, 859 CO_TL_ENTITY, 860 entitySet[i].tei_instance, 861 0, 862 sizeof(MIB_TCPROW), 863 (PVOID *)&IpTcpTable, 864 &returnSize); 865 866 if (status == STATUS_SUCCESS) totalNumber += returnSize; 867 if (IpTcpTable) { 868 tdiFreeThingSet(IpTcpTable); 869 IpTcpTable = NULL; 870 } 871 } 872 } 873 874 closeTcpFile(tcpFile); 875 if (entitySet) tdiFreeThingSet(entitySet); 876 return totalNumber; 877} 878 879PVOID getTcpTable(CLASS_TABLE Class) 880{ 881 DWORD numEntities, returnSize; 882 TDIEntityID *entitySet; 883 HANDLE tcpFile; 884 int i, totalNumber, TmpIdx, CurrIdx = 0; 885 NTSTATUS status; 886 PMIB_TCPTABLE IpTcpTable = NULL; 887 PVOID AdapterTcpTable = NULL; 888 889 TRACE("called.\n"); 890 891 totalNumber = getNumTcpEntries(); 892 893 status = openTcpFile(&tcpFile, FILE_READ_DATA); 894 if (!NT_SUCCESS(status)) 895 { 896 ERR("openTcpFile returned 0x%08lx\n", status); 897 return 0; 898 } 899 900 IpTcpTable = HeapAlloc(GetProcessHeap(), 0, 901 UdpTcpTableCall[Class].TcpOffset + (UdpTcpTableCall[Class].TcpSize * totalNumber)); 902 if (!IpTcpTable) { 903 closeTcpFile(tcpFile); 904 return NULL; 905 } 906 907 status = tdiGetEntityIDSet(tcpFile, &entitySet, &numEntities); 908 909 for (i = 0; i < numEntities; i++) { 910 if (entitySet[i].tei_entity == CO_TL_ENTITY && hasArp(tcpFile, &entitySet[i])) 911 { 912 status = tdiGetSetOfThings(tcpFile, 913 INFO_CLASS_PROTOCOL, 914 INFO_TYPE_PROVIDER, 915 UdpTcpTableCall[Class].TOIID, 916 CO_TL_ENTITY, 917 entitySet[i].tei_instance, 918 0, 919 UdpTcpTableCall[Class].TcpSize, 920 &AdapterTcpTable, 921 &returnSize); 922 923 if (status == STATUS_SUCCESS) { 924 for (TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++) 925 CopyMemory(Add2Ptr(IpTcpTable, UdpTcpTableCall[Class].TcpOffset + UdpTcpTableCall[Class].TcpSize * CurrIdx), 926 Add2Ptr(AdapterTcpTable, UdpTcpTableCall[Class].TcpSize * TmpIdx), 927 UdpTcpTableCall[Class].TcpSize); 928 tdiFreeThingSet(AdapterTcpTable); 929 } 930 } 931 } 932 933 closeTcpFile(tcpFile); 934 tdiFreeThingSet(entitySet); 935 IpTcpTable->dwNumEntries = CurrIdx; 936 return IpTcpTable; 937}