30 typedef struct _PH_NETWORK_CONNECTION
37 LARGE_INTEGER CreateTime;
41 typedef struct _PH_NETWORK_ITEM_QUERY_DATA
43 SLIST_ENTRY ListEntry;
51 typedef struct _PHP_RESOLVE_CACHE_ITEM
58 _Out_writes_bytes_opt_(*pdwSize) PVOID pTcpTable,
59 _Inout_ PDWORD pdwSize,
62 _In_ TCP_TABLE_CLASS TableClass,
67 _Out_writes_bytes_opt_(*pdwSize) PVOID pUdpTable,
68 _Inout_ PDWORD pdwSize,
71 _In_ UDP_TABLE_CLASS TableClass,
76 _In_ WORD wVersionRequested,
77 _Out_ LPWSADATA lpWSAData
83 _In_reads_bytes_(SockaddrLength) const SOCKADDR *pSockaddr,
84 _In_ socklen_t SockaddrLength,
85 _Out_writes_opt_(NodeBufferSize) PWCHAR pNodeBuffer,
86 _In_ DWORD NodeBufferSize,
87 _Out_writes_opt_(ServiceBufferSize) PWCHAR pServiceBuffer,
88 _In_ DWORD ServiceBufferSize,
93 _In_reads_bytes_(len) const
char *addr,
123 _Out_ PULONG NumberOfConnections
143 static
PH_QUEUED_LOCK PhpResolveCacheHashtableLock = PH_QUEUED_LOCK_INIT;
145 static BOOLEAN NetworkImportDone =
FALSE;
149 static _WSAGetLastError WSAGetLastError_I;
165 RtlInitializeSListHead(&PhNetworkItemQueryListHead);
241 _In_ ULONG ProtocolType,
261 &lookupNetworkItemPtr
266 networkItem = *networkItemPtr;
316 lookupCacheItem.Address = *Address;
319 PhpResolveCacheHashtable,
324 return *cacheItemPtr;
333 struct sockaddr_in ipv4Address;
334 struct sockaddr_in6 ipv6Address;
335 struct sockaddr *address;
344 ipv4Address.sin_family = AF_INET;
345 ipv4Address.sin_port = 0;
346 ipv4Address.sin_addr = Address->InAddr;
347 address = (
struct sockaddr *)&ipv4Address;
348 length =
sizeof(ipv4Address);
352 ipv6Address.sin6_family = AF_INET6;
353 ipv6Address.sin6_port = 0;
354 ipv6Address.sin6_flowinfo = 0;
355 ipv6Address.sin6_addr = Address->In6Addr;
356 ipv6Address.sin6_scope_id = 0;
357 address = (
struct sockaddr *)&ipv6Address;
358 length =
sizeof(ipv6Address);
371 (ULONG)hostName->
Length / 2 + 1,
385 (ULONG)hostName->
Length / 2 + 1,
422 data->HostString = hostString;
433 cacheItem->Address = data->Address;
434 cacheItem->HostString = hostString;
444 dprintf(
"resolve failed, error %u\n", WSAGetLastError_I());
450 data->HostString = cacheItem->HostString;
455 return STATUS_SUCCESS;
470 data->NetworkItem = NetworkItem;
471 data->Remote = Remote;
474 data->Address = NetworkItem->RemoteEndpoint.Address;
476 data->Address = NetworkItem->LocalEndpoint.Address;
494 if (*(PULONG64)NetworkItem->OwnerInfo)
500 serviceTag = (PVOID)*(PULONG)NetworkItem->OwnerInfo;
513 ULONG numberOfConnections;
516 if (!NetworkImportDone)
522 iphlpapi = LoadLibrary(L
"iphlpapi.dll");
523 GetExtendedTcpTable_I = (PVOID)GetProcAddress(iphlpapi,
"GetExtendedTcpTable");
524 GetExtendedUdpTable_I = (PVOID)GetProcAddress(iphlpapi,
"GetExtendedUdpTable");
525 ws2_32 = LoadLibrary(L
"ws2_32.dll");
526 WSAStartup_I = (PVOID)GetProcAddress(ws2_32,
"WSAStartup");
527 WSAGetLastError_I = (PVOID)GetProcAddress(ws2_32,
"WSAGetLastError");
528 GetNameInfoW_I = (PVOID)GetProcAddress(ws2_32,
"GetNameInfoW");
529 gethostbyaddr_I = (PVOID)GetProcAddress(ws2_32,
"gethostbyaddr");
534 WSAStartup_I(MAKEWORD(2, 2), &wsaData);
537 NetworkImportDone =
TRUE;
544 PPH_LIST connectionsToRemove = NULL;
552 BOOLEAN found =
FALSE;
554 for (i = 0; i < numberOfConnections; i++)
557 (*networkItem)->ProtocolType == connections[i].ProtocolType &&
558 PhEqualIpEndpoint(&(*networkItem)->LocalEndpoint, &connections[i].LocalEndpoint) &&
559 PhEqualIpEndpoint(&(*networkItem)->RemoteEndpoint, &connections[i].RemoteEndpoint) &&
560 (*networkItem)->ProcessId == connections[i].ProcessId
572 if (!connectionsToRemove)
579 if (connectionsToRemove)
583 for (i = 0; i < connectionsToRemove->
Count; i++)
606 PhMoveReference(&data->NetworkItem->RemoteHostString, data->HostString);
608 PhMoveReference(&data->NetworkItem->LocalHostString, data->HostString);
610 data->NetworkItem->JustResolved =
TRUE;
617 for (i = 0; i < numberOfConnections; i++)
623 connections[i].ProtocolType,
624 &connections[i].LocalEndpoint,
625 &connections[i].RemoteEndpoint,
639 networkItem->
ProtocolType = connections[i].ProtocolType;
642 networkItem->
State = connections[i].State;
643 networkItem->
ProcessId = connections[i].ProcessId;
644 networkItem->
CreateTime = connections[i].CreateTime;
737 BOOLEAN modified =
FALSE;
743 if (networkItem->
State != connections[i].State)
745 networkItem->
State = connections[i].State;
790 _In_ ULONG ProtocolType
793 switch (ProtocolType)
814 case MIB_TCP_STATE_CLOSED:
816 case MIB_TCP_STATE_LISTEN:
818 case MIB_TCP_STATE_SYN_SENT:
820 case MIB_TCP_STATE_SYN_RCVD:
821 return L
"SYN Received";
822 case MIB_TCP_STATE_ESTAB:
823 return L
"Established";
824 case MIB_TCP_STATE_FIN_WAIT1:
825 return L
"FIN Wait 1";
826 case MIB_TCP_STATE_FIN_WAIT2:
827 return L
"FIN Wait 2";
828 case MIB_TCP_STATE_CLOSE_WAIT:
829 return L
"Close Wait";
830 case MIB_TCP_STATE_CLOSING:
832 case MIB_TCP_STATE_LAST_ACK:
834 case MIB_TCP_STATE_TIME_WAIT:
836 case MIB_TCP_STATE_DELETE_TCB:
837 return L
"Delete TCB";
845 _Out_ PULONG NumberOfConnections
850 PMIB_TCPTABLE_OWNER_MODULE tcp4Table;
851 PMIB_UDPTABLE_OWNER_MODULE udp4Table;
852 PMIB_TCP6TABLE_OWNER_MODULE tcp6Table;
853 PMIB_UDP6TABLE_OWNER_MODULE udp6Table;
859 if (!GetExtendedTcpTable_I || !GetExtendedUdpTable_I)
865 GetExtendedTcpTable_I(NULL, &tableSize,
FALSE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0);
866 table = PhAllocate(tableSize);
868 if (GetExtendedTcpTable_I(table, &tableSize,
FALSE, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) == 0)
871 count += tcp4Table->dwNumEntries;
882 GetExtendedTcpTable_I(NULL, &tableSize,
FALSE, AF_INET6, TCP_TABLE_OWNER_MODULE_ALL, 0);
891 if (WindowsVersion <= WINDOWS_XP && tableSize >= FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table))
893 tableSize = FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table) +
894 (tableSize - FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table)) /
sizeof(MIB_TCP6ROW_OWNER_PID) *
sizeof(MIB_TCP6ROW_OWNER_MODULE);
897 table = PhAllocate(tableSize);
899 if (GetExtendedTcpTable_I(table, &tableSize,
FALSE, AF_INET6, TCP_TABLE_OWNER_MODULE_ALL, 0) == 0)
902 count += tcp6Table->dwNumEntries;
913 GetExtendedUdpTable_I(NULL, &tableSize,
FALSE, AF_INET, UDP_TABLE_OWNER_MODULE, 0);
914 table = PhAllocate(tableSize);
916 if (GetExtendedUdpTable_I(table, &tableSize,
FALSE, AF_INET, UDP_TABLE_OWNER_MODULE, 0) == 0)
919 count += udp4Table->dwNumEntries;
930 GetExtendedUdpTable_I(NULL, &tableSize,
FALSE, AF_INET6, UDP_TABLE_OWNER_MODULE, 0);
931 table = PhAllocate(tableSize);
933 if (GetExtendedUdpTable_I(table, &tableSize,
FALSE, AF_INET6, UDP_TABLE_OWNER_MODULE, 0) == 0)
936 count += udp6Table->dwNumEntries;
949 for (i = 0; i < tcp4Table->dwNumEntries; i++)
954 connections[index].LocalEndpoint.Address.Ipv4 = tcp4Table->table[i].dwLocalAddr;
955 connections[index].LocalEndpoint.Port = _byteswap_ushort((USHORT)tcp4Table->table[i].dwLocalPort);
958 connections[index].RemoteEndpoint.Address.Ipv4 = tcp4Table->table[i].dwRemoteAddr;
959 connections[index].RemoteEndpoint.Port = _byteswap_ushort((USHORT)tcp4Table->table[i].dwRemotePort);
961 connections[index].State = tcp4Table->table[i].dwState;
962 connections[index].ProcessId = (HANDLE)tcp4Table->table[i].dwOwningPid;
963 connections[index].CreateTime = tcp4Table->table[i].liCreateTimestamp;
965 connections[index].OwnerInfo,
966 tcp4Table->table[i].OwningModuleInfo,
978 for (i = 0; i < tcp6Table->dwNumEntries; i++)
983 memcpy(connections[index].LocalEndpoint.Address.Ipv6, tcp6Table->table[i].ucLocalAddr, 16);
984 connections[index].LocalEndpoint.Port = _byteswap_ushort((USHORT)tcp6Table->table[i].dwLocalPort);
987 memcpy(connections[index].RemoteEndpoint.Address.Ipv6, tcp6Table->table[i].ucRemoteAddr, 16);
988 connections[index].RemoteEndpoint.Port = _byteswap_ushort((USHORT)tcp6Table->table[i].dwRemotePort);
990 connections[index].State = tcp6Table->table[i].dwState;
991 connections[index].ProcessId = (HANDLE)tcp6Table->table[i].dwOwningPid;
992 connections[index].CreateTime = tcp6Table->table[i].liCreateTimestamp;
994 connections[index].OwnerInfo,
995 tcp6Table->table[i].OwningModuleInfo,
1007 for (i = 0; i < udp4Table->dwNumEntries; i++)
1012 connections[index].LocalEndpoint.Address.Ipv4 = udp4Table->table[i].dwLocalAddr;
1013 connections[index].LocalEndpoint.Port = _byteswap_ushort((USHORT)udp4Table->table[i].dwLocalPort);
1015 connections[index].RemoteEndpoint.Address.Type = 0;
1017 connections[index].State = 0;
1018 connections[index].ProcessId = (HANDLE)udp4Table->table[i].dwOwningPid;
1019 connections[index].CreateTime = udp4Table->table[i].liCreateTimestamp;
1021 connections[index].OwnerInfo,
1022 udp4Table->table[i].OwningModuleInfo,
1034 for (i = 0; i < udp6Table->dwNumEntries; i++)
1039 memcpy(connections[index].LocalEndpoint.Address.Ipv6, udp6Table->table[i].ucLocalAddr, 16);
1040 connections[index].LocalEndpoint.Port = _byteswap_ushort((USHORT)udp6Table->table[i].dwLocalPort);
1042 connections[index].RemoteEndpoint.Address.Type = 0;
1044 connections[index].State = 0;
1045 connections[index].ProcessId = (HANDLE)udp6Table->table[i].dwOwningPid;
1046 connections[index].CreateTime = udp6Table->table[i].liCreateTimestamp;
1048 connections[index].OwnerInfo,
1049 udp6Table->table[i].OwningModuleInfo,
1059 *NumberOfConnections = count;
1060 *Connections = connections;