Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Кулаков В.Г. Методические указания к лабораторн...doc
Скачиваний:
5
Добавлен:
04.05.2019
Размер:
286.72 Кб
Скачать

5.3. Функции для определения состояния портов

Если нужно узнать состояние портов локального компьютера, нет необходимости сканировать порты. Есть способ лучше – запросить состояние всех портов с помощью функций GetTcpTable и GetUdpTable.

Данные о TCP-портах хранятся в виде таблицы в структуре типа _MIB_TCPTABLE:

typedef struct _MIB_TCPTABLE { DWORD dwNumEntries; MIB_TCPROW table[ANY_SIZE];

} MIB_TCPTABLE, *PMIB_TCPTABLE;

Переменная dwNumEntries хранит значение, соответствующее количеству элементов в таблице. Структура MIB_TCPROW описывает состояние TCP-порта:

typedef struct _MIB_TCPROW { DWORD dwState; DWORD dwLocalAddr; DWORD dwLocalPort; DWORD dwRemoteAddr; DWORD dwRemotePort;

} MIB_TCPROW, *PMIB_TCPROW;

Поля структуры имеют следующее назначение:

  • dwState – состояние порта;

  • dwLocalAddr – локальный адрес (интерфейс, на котором открыт порт);

  • dwLocalPort – локальный порт (порт, который открыт на компьютере);

  • dwRemoteAddr – удаленный адрес (адрес, с которого в данный момент установлено соединение с портом);

  • dwRemotePort – удаленный порт (порт на удаленной машине, через который происходит обращение к локальной машине).

Функция DWORD GetTcpTable(PMIB_TCPTABLE pTcpTable, PDWORD pdwSize, BOOL bOrder) имеет три параметра: указатель на структуру MIB_TCPTABLE, размер этой структуры и признак сортировки (если указано TRUE, то таблица будет отсортирована по номеру порта).

Если в качестве первых двух параметров указать нулевое значение, то во втором параметре будет получен необходимый размер для хранения структур PMIB_TCPTABLE. Для выделения памяти необходимо воспользоваться функцией malloc.

Повторный вызов функции GetTcpTable позволяет через первый параметр (переменная рТсрTаblе типа PMIB_TCPTABLE) получить данные о состоянии всех TCP-портов. Их количество находится в параметре dwNumEntries структуры рТсрTаblе. Информацию об определенном порте можно узнать из параметра table[i], где i – номер порта.

Данные о UDP-портах хранятся в виде таблицы в структуре типа _MIB_UDPTABLE:

typedef struct _MIB_UDPTABLE { DWORD dwNumEntries; MIB_UDPROW table[ANY_SIZE];

} MIB_UDPTABLE, *PMIB_UDPTABLE;

Переменная dwNumEntries хранит значение, соответствующее количеству элементов в таблице.

Структура MIB_UDPROW описывает состояние UDP-порта:

typedef struct _MIB_UDPROW { DWORD dwLocalAddr; DWORD dwLocalPort;

} MIB_UDPROW, *PMIB_UDPROW;

Поля структуры имеют следующее назначение:

  • dwLocalAddr – локальный адрес (интерфейс, на котором открыт порт);

  • dwLocalPort – локальный порт (порт, который открыт на компьютере).

Для получения таблицы UDP-портов используется функция

DWORD GetUdpTable(PMIB_UDPTABLE pUdpTable, PDWORD pdwSize, BOOL bOrder). Она используется аналогично GetTcpTable, но узнать можно только локальный адрес и локальный порт, потому что протокол UDP не устанавливает соединения (нет сведений об удаленном компьютере).

Пример программы, которая отображает состояние портов TCP и UDP, приведен в листинге 5.2.

Листинг 5.2. Проверка состояния портов TCP и UDP

#include "stdafx.h"

#include <winsock2.h>

#include <windows.h>

#include <iphlpapi.h>

#include <assert.h>

#include <malloc.h>

int main(int argc, _TCHAR* argv[])

{

DWORD dwStatus = NO_ERROR;

PMIB_TCPTABLE pTcpTable = NULL;

DWORD dwActualSize = 0;

dwStatus = GetTcpTable(pTcpTable, &dwActualSize, TRUE);

pTcpTable = (PMIB_TCPTABLE) malloc(dwActualSize);

assert(pTcpTable);

dwStatus = GetTcpTable(pTcpTable, &dwActualSize, TRUE);

if (dwStatus != NO_ERROR)

{

printf("Couldn't get tcp connection table.\n");

free(pTcpTable); getchar(); return -1;

}

struct in_addr inadLocal, inadRemote;

DWORD dwRemotePort = 0;

char szLocalIp[1000];

char szRemIp[1000];

if (pTcpTable != NULL)

{

printf("==========================================\n");

printf("TCP table:\n\n");

printf(

"Loc Addr\tLoc Port\tRem Addr\tRem Port\tState\n\n");

for (UINT i=0; i<pTcpTable->dwNumEntries; i++)

{

inadLocal.s_addr = pTcpTable->table[i].dwLocalAddr;

inadRemote.s_addr = pTcpTable->table[i].dwRemoteAddr;

strcpy(szLocalIp, inet_ntoa(inadLocal));

strcpy(szRemIp, inet_ntoa(inadRemote));

if(pTcpTable->table[i].dwState==MIB_TCP_STATE_LISTEN)

dwRemotePort = pTcpTable->table[i].dwRemotePort;

else dwRemotePort = 0;

printf("%-15s %u\t\t%-15s %u\t\t", szLocalIp,

ntohs((unsigned short)(0x0000FFFF &

pTcpTable->table[i].dwLocalPort)),

szRemIp, ntohs((unsigned short)(0x0000FFFF &

dwRemotePort)));

switch (pTcpTable->table[i].dwState)

{

case MIB_TCP_STATE_LISTEN:

printf("Listen"); break;

case MIB_TCP_STATE_CLOSED:

printf("Closed"); break;

case MIB_TCP_STATE_TIME_WAIT:

printf("Time wait"); break;

case MIB_TCP_STATE_LAST_ACK:

printf("Last ACK"); break;

case MIB_TCP_STATE_CLOSING:

printf("Closing"); break;

case MIB_TCP_STATE_CLOSE_WAIT:

printf("Close Wait"); break;

case MIB_TCP_STATE_FIN_WAIT1:

printf("FIN wait"); break;

case MIB_TCP_STATE_ESTAB:

printf("EStab"); break;

case MIB_TCP_STATE_SYN_RCVD:

printf("SYN Received"); break;

case MIB_TCP_STATE_SYN_SENT:

printf("SYN Sent"); break;

case MIB_TCP_STATE_DELETE_TCB: printf("Delete");

}

printf("\n");

}

}

free(pTcpTable);

getchar();

dwStatus = NO_ERROR;

PMIB_UDPTABLE pUdpTable = NULL;

dwActualSize = 0;

dwStatus = GetUdpTable(pUdpTable, &dwActualSize, TRUE);

pUdpTable = (PMIB_UDPTABLE) malloc(dwActualSize);

assert(pUdpTable);

dwStatus = GetUdpTable(pUdpTable, &dwActualSize, TRUE);

if (dwStatus != NO_ERROR)

{

printf("Couldn't get udp connection table.\n");

free(pUdpTable); getchar(); return -2;

}

if (pUdpTable != NULL)

{

printf("==========================================\n");

printf("UDP table:\n\n");

printf("Loc Addr\tLoc Port\n\n");

for (UINT i = 0; i < pUdpTable->dwNumEntries; i++)

{

inadLocal.s_addr = pUdpTable->table[i].dwLocalAddr;

printf("%-15s %u\n", inet_ntoa(inadLocal),

ntohs((unsigned short)(0x0000FFFF &

pUdpTable->table[i].dwLocalPort)));

}

}

free(pUdpTable);

getchar();

return 0;

}