본문 바로가기
개발 언어/C,VC++

윈도우 환경에서 특정 포트를 리슨하고 있는 프로세스의 정보 조회 방법

by 주호파파 2012. 5. 24.
728x90
반응형

다음은 "윈도우 환경에서 특정 포트를 리슨하고 있는, 프로세스의 정보 조회 방법"에 대해서 설명하고 있습니다.

#pragma comment(lib, "ws2_32.lib")
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <string.h>

#if defined NTDDI_VERSION && (NTDDI_VERSION >= NTDDI_LONGHORN)
#  include <Iphlpapi.h>
/* Windows Vista Higher                 */
#else

#  ifndef ANY_SIZE
#    define ANY_SIZE 1
#  endif

    /* for Windows 2K, Windows XP, Windows 2003 */
    typedef struct _MIB_TCPROW_OWNER_PID
    {
        DWORD       dwState;
        DWORD       dwLocalAddr;
        DWORD       dwLocalPort;
        DWORD       dwRemoteAddr;
        DWORD       dwRemotePort;
        DWORD       dwOwningPid;
    } MIB_TCPROW_OWNER_PID, *PMIB_TCPROW_OWNER_PID;

    typedef struct _MIB_TCPTABLE_OWNER_PID
    {
        DWORD                dwNumEntries;
        MIB_TCPROW_OWNER_PID table[ANY_SIZE];
    } MIB_TCPTABLE_OWNER_PID, *PMIB_TCPTABLE_OWNER_PID;

    typedef struct _MIB_TCP6ROW_OWNER_PID
    {
        UCHAR           ucLocalAddr[16];
        DWORD           dwLocalScopeId;
        DWORD           dwLocalPort;
        UCHAR           ucRemoteAddr[16];
        DWORD           dwRemoteScopeId;
        DWORD           dwRemotePort;
        DWORD           dwState;
        DWORD           dwOwningPid;
    } MIB_TCP6ROW_OWNER_PID, *PMIB_TCP6ROW_OWNER_PID;

    typedef struct _MIB_TCP6TABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_TCP6ROW_OWNER_PID   table[ANY_SIZE];
    } MIB_TCP6TABLE_OWNER_PID, *PMIB_TCP6TABLE_OWNER_PID;

    typedef struct _MIB_UDPROW_OWNER_PID {
        DWORD dwLocalAddr;
        DWORD dwLocalPort;
        DWORD dwOwningPid;
    } MIB_UDPROW_OWNER_PID, *PMIB_UDPROW_OWNER_PID;

    typedef struct _MIB_UDPTABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_UDPROW_OWNER_PID    table[ANY_SIZE];
    } MIB_UDPTABLE_OWNER_PID, *PMIB_UDPTABLE_OWNER_PID;

    typedef struct _MIB_UDP6ROW_OWNER_PID {
        UCHAR           ucLocalAddr[16];
        DWORD           dwLocalScopeId;
        DWORD           dwLocalPort;
        DWORD           dwOwningPid;
    } MIB_UDP6ROW_OWNER_PID, *PMIB_UDP6ROW_OWNER_PID;

    typedef struct _MIB_UDP6TABLE_OWNER_PID
    {
        DWORD                   dwNumEntries;
        MIB_UDP6ROW_OWNER_PID   table[ANY_SIZE];
    } MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;

    typedef enum _TCP_TABLE_CLASS {
        TCP_TABLE_BASIC_LISTENER,
        TCP_TABLE_BASIC_CONNECTIONS,
        TCP_TABLE_BASIC_ALL,
        TCP_TABLE_OWNER_PID_LISTENER,
        TCP_TABLE_OWNER_PID_CONNECTIONS,
        TCP_TABLE_OWNER_PID_ALL,
        TCP_TABLE_OWNER_MODULE_LISTENER,
        TCP_TABLE_OWNER_MODULE_CONNECTIONS,
        TCP_TABLE_OWNER_MODULE_ALL
    } TCP_TABLE_CLASS, *PTCP_TABLE_CLASS;

    typedef enum _UDP_TABLE_CLASS {
        UDP_TABLE_BASIC,
        UDP_TABLE_OWNER_PID,
        UDP_TABLE_OWNER_MODULE
    } UDP_TABLE_CLASS, *PUDP_TABLE_CLASS;


    typedef enum {
        MIB_TCP_STATE_CLOSED     =  1,
        MIB_TCP_STATE_LISTEN     =  2,
        MIB_TCP_STATE_SYN_SENT   =  3,
        MIB_TCP_STATE_SYN_RCVD   =  4,
        MIB_TCP_STATE_ESTAB      =  5,
        MIB_TCP_STATE_FIN_WAIT1  =  6,
        MIB_TCP_STATE_FIN_WAIT2  =  7,
        MIB_TCP_STATE_CLOSE_WAIT =  8,
        MIB_TCP_STATE_CLOSING    =  9,
        MIB_TCP_STATE_LAST_ACK   = 10,
        MIB_TCP_STATE_TIME_WAIT  = 11,
        MIB_TCP_STATE_DELETE_TCB = 12,
    } MIB_TCP_STATE;

#endif

typedef struct _MIB_TCPROW_EX
{
    DWORD dwState;
    DWORD dwLocalAddr;
    DWORD dwLocalPort;
    DWORD dwRemoteAddr;
    DWORD dwRemotePort;
    DWORD dwProcessId;
} MIB_TCPROW_EX, *PMIB_TCPROW_EX;

typedef struct _MIB_TCPTABLE_EX
{
    DWORD dwNumEntries;
    MIB_TCPROW_EX table[ANY_SIZE];
} MIB_TCPTABLE_EX, *PMIB_TCPTABLE_EX;

typedef struct _MIB_TCP6ROW_EX {
    UCHAR ucLocalAddr[16];
    DWORD dwLocalScopeId;
    DWORD dwLocalPort;
    UCHAR ucRemoteAddr[16];
    DWORD dwRemoteScopeId;
    DWORD dwRemotePort;
    DWORD dwState;
    DWORD dwProcessId;
} MIB_TCP6ROW_EX, *PMIB_TCP6ROW_EX;

typedef struct _MIB_TCP6TABLE_EX {
    DWORD dwNumEntries;
    MIB_TCP6ROW_EX table[ANY_SIZE];
} MIB_TCP6TABLE_EX, *PMIB_TCP6TABLE_EX;

typedef struct _MIB_UDPROW_EX
{
    DWORD dwLocalAddr;
    DWORD dwLocalPort;
    DWORD dwProcessId;
} MIB_UDPROW_EX, *PMIB_UDPROW_EX;

typedef struct _MIB_UDPTABLE_EX
{
    DWORD dwNumEntries;
    MIB_UDPROW_EX table[ANY_SIZE];
} MIB_UDPTABLE_EX, *PMIB_UDPTABLE_EX;

typedef struct _MIB_UDP6ROW_EX {
    UCHAR ucLocalAddr[16];
    DWORD dwLocalScopeId;
    DWORD dwLocalPort;
    DWORD dwProcessId;
} MIB_UDP6ROW_EX, *PMIB_UDP6ROW_EX;

typedef struct _MIB_UDP6TABLE_EX {
    DWORD dwNumEntries;
    MIB_UDP6ROW_EX table[ANY_SIZE];
} MIB_UDP6TABLE_EX,  *PMIB_UDP6TABLE_EX;

typedef DWORD (WINAPI *GetExtendedTcpTable_t)(PVOID pTcpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, TCP_TABLE_CLASS TableClass, ULONG Reserved);
typedef DWORD (WINAPI *GetExtendedUdpTable_t)(PVOID pUdpTable, PDWORD pdwSize, BOOL bOrder, ULONG ulAf, UDP_TABLE_CLASS TableClass, ULONG Reserved);
typedef DWORD (WINAPI *AllocateAndGetTcpExTableFromStack_t)(PVOID *ppTcpTable, BOOL bOrder, HANDLE hHeap, DWORD dwFlags, DWORD dwFamily);
typedef DWORD (WINAPI *AllocateAndGetUdpExTableFromStack_t)(PVOID *ppUDPTable, BOOL bOrder, HANDLE hHeap, DWORD dwFlags, DWORD dwFamily);
int NetStat();
int NetStatEx();
BOOL IsVista();

int main(int argc, char **argv)
{
    return ( IsVista() ) ? NetStatEx() : NetStat();    
}

BOOL IsVista()
{
    OSVERSIONINFO osver;

    osver.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
    
    if ( GetVersionEx (&osver) )
    {
        if ( osver.dwPlatformId == VER_PLATFORM_WIN32_NT && (osver.dwMajorVersion >= 6 ) )
            return TRUE;
    }

    return FALSE;
}

int NetStatEx()
{
    DWORD i = 0, dwRet = 0;
    DWORD dwTcpSize = 0, dwTcp6Size = 0;
    DWORD dwUdpSize = 0, dwUdp6Size = 0;
    
    MIB_TCPTABLE_OWNER_PID  *pTcp  = NULL;
    MIB_TCP6TABLE_OWNER_PID *pTcp6 = NULL;
    MIB_UDPTABLE_OWNER_PID  *pUdp  = NULL;
    MIB_UDP6TABLE_OWNER_PID *pUdp6 = NULL;

    GetExtendedTcpTable_t GetExtendedTcpTable;
    GetExtendedUdpTable_t GetExtendedUdpTable;

    HMODULE hDLL = NULL;
    
    if ( (hDLL = LoadLibrary("Iphlpapi.dll")) == NULL )
    {
        printf("fail to LoadLibrary 'Iphlpapi.dll'\n");
        return -1;
    }

    GetExtendedTcpTable = (GetExtendedTcpTable_t)GetProcAddress(hDLL, "GetExtendedTcpTable");
    GetExtendedUdpTable = (GetExtendedUdpTable_t)GetProcAddress(hDLL, "GetExtendedUdpTable");

    dwRet = GetExtendedTcpTable(NULL, &dwTcpSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedTcpTable(NULL, &dwTcp6Size, TRUE, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0);
    
    dwRet = GetExtendedUdpTable(NULL, &dwUdpSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
    dwRet = GetExtendedUdpTable(NULL, &dwUdp6Size, TRUE, AF_INET6, UDP_TABLE_OWNER_PID, 0);
        
    pTcp  = (MIB_TCPTABLE_OWNER_PID  *)malloc(dwTcpSize);
    pTcp6 = (MIB_TCP6TABLE_OWNER_PID *)malloc(dwTcp6Size);
    pUdp  = (MIB_UDPTABLE_OWNER_PID  *)malloc(dwUdpSize);
    pUdp6 = (MIB_UDP6TABLE_OWNER_PID *)malloc(dwUdp6Size);

    dwRet = GetExtendedTcpTable(pTcp, &dwTcpSize, TRUE, AF_INET, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedTcpTable(pTcp6, &dwTcp6Size, TRUE, AF_INET6, TCP_TABLE_OWNER_PID_ALL, 0);
    dwRet = GetExtendedUdpTable(pUdp, &dwUdpSize, TRUE, AF_INET, UDP_TABLE_OWNER_PID, 0);
    dwRet = GetExtendedUdpTable(pUdp6, &dwUdp6Size, TRUE, AF_INET6, UDP_TABLE_OWNER_PID, 0);

    for ( i = 0; i < pTcp->dwNumEntries; i++ )
    {
        printf("IPv4 TCP Port %-10d ", ntohs( (u_short)pTcp->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pTcp->table[i].dwOwningPid);
    }

    for ( i = 0; i < pTcp6->dwNumEntries; i++ )
    {
        printf("IPv6 TCP Port %-10d ", ntohs( (u_short)pTcp6->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pTcp6->table[i].dwOwningPid);
    }

    for ( i = 0; i < pUdp->dwNumEntries; i++ )
    {
        printf("IPv4 UDP Port %-10d ", ntohs( (u_short)pUdp->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pUdp->table[i].dwOwningPid);
    }

    for ( i = 0; i < pUdp6->dwNumEntries; i++ )
    {
        printf("IPv6 UDP Port %-10d ", ntohs( (u_short)pUdp6->table[i].dwLocalPort));
        printf("Owner process id %d\n",  pUdp6->table[i].dwOwningPid);
    }

    if ( pTcp )
        free(pTcp);

    if ( pTcp6 )
        free(pTcp6);

    if ( pUdp )
        free(pUdp);

    if ( pUdp6 )
        free(pUdp6);

    FreeLibrary(hDLL);

    return 0;   
}

int NetStat()
{
    DWORD i = 0;
    HMODULE hDLL = NULL;
    HANDLE hHeap = NULL;
    PMIB_TCPTABLE_EX pTcp = NULL;
    PMIB_UDPTABLE_EX pUdp = NULL;
    PMIB_TCP6TABLE_EX pTcp6 = NULL;
    PMIB_UDP6TABLE_EX pUdp6 = NULL;
        
    AllocateAndGetTcpExTableFromStack_t AllocateAndGetTcpExTableFromStack = NULL;
    AllocateAndGetUdpExTableFromStack_t AllocateAndGetUdpExTableFromStack = NULL;

    hHeap = GetProcessHeap();

    if ( (hDLL = LoadLibrary("iphlpapi.dll")) == NULL )
        return -1;

    if ( (AllocateAndGetTcpExTableFromStack = (AllocateAndGetTcpExTableFromStack_t)GetProcAddress(hDLL, "AllocateAndGetTcpExTableFromStack")) == NULL )
        return -1;

    if ( (AllocateAndGetUdpExTableFromStack = (AllocateAndGetUdpExTableFromStack_t)GetProcAddress(hDLL,"AllocateAndGetUdpExTableFromStack")) == NULL )
        return -1;

    if ( AllocateAndGetTcpExTableFromStack((PVOID *)&pTcp, TRUE, hHeap, 0, AF_INET) == NO_ERROR )
    {
        for ( i = 0; i < pTcp->dwNumEntries; i++ )
        {
            printf("IPv4 TCP Port %-10d ", ntohs( (u_short)pTcp->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pTcp->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetTcpExTableFromStack((PVOID *)&pTcp6, TRUE, hHeap, 0, AF_INET6) == NO_ERROR )
    {
        for ( i = 0; i < pTcp6->dwNumEntries; i++ )
        {
            printf("IPv6 TCP Port %-10d ", ntohs( (u_short)pTcp6->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pTcp6->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetUdpExTableFromStack((PVOID *)&pUdp, TRUE, hHeap, 0, AF_INET) == NO_ERROR )
    {
        for ( i = 0; i < pUdp->dwNumEntries; i++ )
        {
            printf("IPv4 UDP Port %-10d ", ntohs( (u_short)pUdp->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pUdp->table[i].dwProcessId);
        }
    }

    if ( AllocateAndGetUdpExTableFromStack((PVOID *)&pUdp6, TRUE, hHeap, 0, AF_INET6) == NO_ERROR )
    {
        for ( i = 0; i < pUdp6->dwNumEntries; i++ )
        {
            printf("IPv6 UDP Port %-10d ", ntohs( (u_short)pUdp6->table[i].dwLocalPort));
            printf("Owner process id %d\n",  pUdp6->table[i].dwProcessId);
        }
    }
        
    if ( pTcp )
        HeapFree(hHeap, 0, pTcp);
    
    if ( pUdp )
        HeapFree(hHeap, 0, pUdp);
    
    if ( pTcp6 )
        HeapFree(hHeap, 0, pTcp6);
    
    if ( pUdp6 )
        HeapFree(hHeap, 0, pUdp6);
    
    FreeLibrary(hDLL);
    
    return 0;
}

※ 설명의 편의상 예외처리를 거의 하지 않았으니, 가져다 쓰실때에는 꼭 예외처리 추가하는 센스 !!!  잊지마세요~~

728x90
반응형