c++ 使用程序id獲取開啟的網路埠
阿新 • • 發佈:2020-09-18
#pragma warning( disable : 4996) #include <winsock2.h> #include <ws2tcpip.h> #include <iphlpapi.h> #include <stdio.h> #include <string> #include <vector> #pragma comment(lib, "iphlpapi.lib") #pragma comment(lib, "ws2_32.lib") #define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x)) #define FREE(x) HeapFree(GetProcessHeap(), 0, (x)) using namespace std; string toIp(DWORD ip) { size_t a = ip >> 24 & 0xFF; size_t b = ip >> 16 & 0xFF; size_t c = ip >> 8 & 0xFF; size_t d = ip & 0xFF; // 資料是大端就用 abcd,小端dcba return string(to_string(d) + "." + to_string(c) + "." + to_string(b) + "." + to_string(a)); } struct ConnectNet { DWORD proto = 0; // 6 tcp,17 udp string src; // src ip u_short sport; // src port string dst; // dst ip u_short dport; // dst port string state; DWORD pid; // process id }; BOOL eachTCP(DWORD pid, vector<ConnectNet>* connectNets) { PMIB_TCPTABLE2 pTcpTable = nullptr; ULONG ulSize = 0; DWORD dwRetVal = 0; // 第一次獲取大小,初始化pTcpTable if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) == ERROR_INSUFFICIENT_BUFFER) { pTcpTable = (MIB_TCPTABLE2*)MALLOC(ulSize); if (pTcpTable == NULL) return 0; } // 第二次獲取資料 if ((dwRetVal = GetTcpTable2(pTcpTable, &ulSize, TRUE)) == NO_ERROR) { if (pTcpTable == NULL) return 0; for (size_t i = 0; i < pTcpTable->dwNumEntries; i++) { auto it = pTcpTable->table[i]; if (pid != it.dwOwningPid && pid != 0) continue; string state = ""; switch (it.dwState) { case MIB_TCP_STATE_CLOSED: state = "CLOSED"; break; case MIB_TCP_STATE_LISTEN: state = "LISTEN"; break; case MIB_TCP_STATE_SYN_SENT: state = ("SYN-SENT"); break; case MIB_TCP_STATE_SYN_RCVD: state = ("SYN-RECEIVED"); break; case MIB_TCP_STATE_ESTAB: state = ("ESTABLISHED"); break; case MIB_TCP_STATE_FIN_WAIT1: state = ("FIN-WAIT-1"); break; case MIB_TCP_STATE_FIN_WAIT2: state = ("FIN-WAIT-2"); break; case MIB_TCP_STATE_CLOSE_WAIT: state = ("CLOSE-WAIT"); break; case MIB_TCP_STATE_CLOSING: state = ("CLOSING"); break; case MIB_TCP_STATE_LAST_ACK: state = ("LAST-ACK"); break; case MIB_TCP_STATE_TIME_WAIT: state = ("TIME-WAIT"); break; case MIB_TCP_STATE_DELETE_TCB: state = ("DELETE-TCB"); break; default: state = ("UNKNOWN dwState value"); break; } connectNets->push_back(ConnectNet{ 6, toIp(it.dwLocalAddr), ntohs((u_short)it.dwLocalPort), toIp(it.dwRemoteAddr), ntohs((u_short)it.dwRemotePort), state, it.dwOwningPid }); } } else { FREE(pTcpTable); return FALSE; } if (pTcpTable != NULL) { FREE(pTcpTable); pTcpTable = NULL; } return TRUE; } BOOL eachUDP(DWORD pid, vector<ConnectNet>* connectNets) { MIB_UDPTABLE_OWNER_PID* pUdpTable = nullptr; ULONG ulSize = 0; DWORD dwRetVal = 0; // 第一次獲取大小,初始化pTcpTable if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, TRUE, AF_INET, UDP_TABLE_CLASS::UDP_TABLE_OWNER_PID, 0)) == ERROR_INSUFFICIENT_BUFFER) { pUdpTable = (MIB_UDPTABLE_OWNER_PID*)MALLOC(ulSize); if (pUdpTable == NULL) return 0; } // 第二次獲取資料 if ((dwRetVal = GetExtendedUdpTable(pUdpTable, &ulSize, TRUE, AF_INET, UDP_TABLE_CLASS::UDP_TABLE_OWNER_PID, 0)) == NO_ERROR) { if (pUdpTable == NULL) return 0; for (size_t i = 0; i < pUdpTable->dwNumEntries; i++) { auto it = pUdpTable->table[i]; if (it.dwOwningPid != pid && pid != 0) continue; connectNets->push_back(ConnectNet{ 17, toIp(it.dwLocalAddr).c_str(), ntohs((u_short)it.dwLocalPort), "*", 0, "", it.dwOwningPid }); } } else { FREE(pUdpTable); return FALSE; } if (pUdpTable != NULL) { FREE(pUdpTable); pUdpTable = NULL; } return TRUE; } BOOL getNetTable(DWORD pid, vector<ConnectNet>* connectNets) { if (!eachTCP(pid, connectNets)) return FALSE; return eachUDP(pid, connectNets); } // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-gettcptable2 // https://docs.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getudptable int main() { vector<ConnectNet> r; if (getNetTable(0, &r)) { for (auto it : r) { if (it.proto == 6) { printf("\t%s\t%s:%d\t%s:%d\t%s\t%d\n", "TCP", it.src.c_str(), it.sport, it.dst.c_str(), it.dport, it.state.c_str(), it.pid); } else if (it.proto == 17) { printf("\t%s\t%s:%d\t%s:%s\t\t%d\n", "UDP", it.src.c_str(), it.sport, it.dst.c_str(), it.dport, it.pid); } } } return 0; }