Getting PID of peer socket on Windows

前端 未结 1 1767
北海茫月
北海茫月 2020-12-22 04:17

I am writing a web proxy and when a request comes in (typically from the browser on the machine), I\'d like to also get the pid and any other requesting application. Is ther

相关标签:
1条回答
  • 2020-12-22 04:43

    What you are asking for is only possible if the client and server are running on the same machine.

    When a client is connected to the proxy, the proxy can use getpeername() to query the socket for the remote client IP/Port (or use the IP/Port reported by accept()) and getsockname() to get its local server IP/Port. Then the proxy can use GetTcpTable2() (IPv4) or GetTcp6Table2() (IPv6) to retrieve a list of active TCP connections and loop through it looking for a connection that matches the IP/Port pairs. If found, the list entry will tell you the process ID that owns that connection.

    For example:

    DWORD GetClientPid(SOCKET client)
    {
        DWORD pid = 0;
    
        sockaddr_in ServerAddr = {0};
        int ServerAddrSize = sizeof(ServerAddr);
    
        sockaddr_in ClientAddr = {0};
        int ClientAddrSize = sizeof(ClientAddr);
    
        if ((getsockname(client, (sockaddr*)&ServerAddr, &ServerAddrSize) == 0) &&
            (getpeername(client, (sockaddr*)&ClientAddr, &ClientAddrSize) == 0))
        {
            PMIB_TCPTABLE2 TcpTable = NULL;
            ULONG TcpTableSize = 0;
            ULONG result;
    
            do
            {
                result = GetTcpTable2(TcpTable, &TcpTableSize, TRUE);
                if (result != ERROR_INSUFFICIENT_BUFFER)
                    break;
    
                LocalFree(TcpTable);
                TcpTable = (PMIB_TCPTABLE2) LocalAlloc(LMEM_FIXED, TcpTableSize);
            }
            while (TcpTable != NULL);
    
            if (result == NO_ERROR)
            {
                for (DWORD dw = 0; dw < TcpTable->dwNumEntries; ++dw)
                {
                    PMIB_TCPROW2 row = &(TcpTable->table[dw]);
    
                    if ((row->dwState == MIB_TCP_STATE_ESTAB) &&
                        (row->dwLocalAddr == ClientAddr.sin_addr.s_addr) &&
                        ((row->dwLocalPort & 0xFFFF) == ClientAddr.sin_port) &&
                        (row->dwRemoteAddr == ServerAddr.sin_addr.s_addr) &&
                        ((row->dwRemotePort & 0xFFFF) == ServerAddr.sin_port))
                    {
                        pid = row->dwOwningPid;
                        break;
                    }
                }
            }
    
            LocalFree(TcpTable);
        }
    
        return pid;
    }
    

    SOCKET client = accept(server, NULL, NULL);
    if (client != INVALID_SOCKET)
    {
        DWORD ClientPid = GetClientPid(client);
        ...
    }
    
    0 讨论(0)
提交回复
热议问题