Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> В неразборчивом режиме recv не принимает ничего 
:(
    Опции темы
Aoizora
Дата 27.11.2016, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016

Репутация: нет
Всего: нет



Мне нужно написать простой анализатор пакетов, который снифает трафик, слегка анализирует пакеты и решает, отбрасывать пакет или нет. Написал такую программу:

Код

#include <Winsock2.h>
#include <Windows.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000

typedef struct tagIPHeader
{
  unsigned char  ver_len;        // версия и длина заголовка
  unsigned char  tos;            // тип сервиса 
  unsigned short length;        // длина всего пакета 
  unsigned short id;            // Id 
  unsigned short flgs_offset;        // флаги и смещение
  unsigned char  ttl;            // время жизни 
  unsigned char  protocol;        // протокол 
  unsigned short xsum;            // контрольная сумма 
  unsigned long  src;            // IP-адрес отправителя 
  unsigned long  dest;            // IP-адрес назначения 
  unsigned short *params;        // параметры (до 320 бит)
  unsigned char  *data;            // данные (до 65535 октетов)
} IPHeader;

void ShowError()
{
        LPVOID lpMsgBuf = NULL;
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            WSAGetLastError(),
            MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf,0,NULL);
        std::cout << (LPCTSTR)lpMsgBuf << std::endl;
        LocalFree(lpMsgBuf);
}

IPHeader* sniff(SOCKET sock)
{
    IPHeader *hdr;
    char buffer[MAX_PACKET_SIZE];
    int count = 0;

    count = recv(sock, buffer, sizeof(buffer), 0);
    if (count >= sizeof(IPHeader))
    {
        hdr = (IPHeader *)malloc(MAX_PACKET_SIZE);
        memcpy(hdr, buffer, MAX_PACKET_SIZE);
        return hdr;
    }
    else
        return 0;
}

int main()
{
        WSADATA wsaData;
        char hostname[128];
        HOSTENT* hostinfo;
        SOCKADDR_IN sockaddr;
        unsigned long flag = 1;

        if(WSAStartup(0x0202, &wsaData)){ ShowError(); }
        else
        {
                std::cout << "WSAStartup - OK" << std::endl;
                SOCKET sock;
                sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
                if(sock == INVALID_SOCKET){ ShowError(); }
                {
                        std::cout << "Raw scoket is created" << std::endl;
                        if(closesocket(sock) == SOCKET_ERROR) { ShowError(); }
                }


                gethostname(hostname, sizeof(hostname));
                hostinfo = gethostbyname(hostname);

                ZeroMemory(&sockaddr, sizeof(sockaddr));
                sockaddr.sin_family = AF_INET;
                sockaddr.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr_list[0])->s_addr;
                bind(sock, (SOCKADDR *)&sockaddr, sizeof(SOCKADDR));

                ioctlsocket(sock, SIO_RCVALL, &flag);

                // Analyze packets
                while (true)
                {
                        IPHeader* hdr = sniff(sock);
                        // обработка IP-пакета
                        if (hdr)
                        { 
                                unsigned char *byte_iterator = (unsigned char *)hdr;
                                for (int i = 0; i < sizeof(IPHeader); i++)
                                {
                                        printf("%02x", *byte_iterator);
                                        ++byte_iterator;
                                }
                        }
                        free(hdr);
                }
                
                if(WSACleanup()) { ShowError(); }
                else
                { std::cout << "WSACleanup - OK" << std::endl;}
        }
        
        return 0;
}



Но при выполнении sniff в цикле функция recv ничего не читает из сокета, и в буфере остается мусор. Что я делаю не так?
PM MAIL   Вверх
Aoizora
Дата 27.11.2016, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016

Репутация: нет
Всего: нет



Добавил несколько проверок. При бинде сокета возвращается ошибка 10014: Bad address. The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).

Я так понимаю, проблема в размере структур, которые я использую в вызове bind?


Код

#include <Winsock2.h>
#include <Windows.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000

typedef struct tagIPHeader
{
  unsigned char  ver_len;        // версия и длина заголовка
  unsigned char  tos;            // тип сервиса 
  unsigned short length;        // длина всего пакета 
  unsigned short id;            // Id 
  unsigned short flgs_offset;        // флаги и смещение
  unsigned char  ttl;            // время жизни 
  unsigned char  protocol;        // протокол 
  unsigned short xsum;            // контрольная сумма 
  unsigned long  src;            // IP-адрес отправителя 
  unsigned long  dest;            // IP-адрес назначения 
  unsigned short *params;        // параметры (до 320 бит)
  unsigned char  *data;            // данные (до 65535 октетов)
} IPHeader;

void ShowError()
{
        LPVOID lpMsgBuf = NULL;
        int error = WSAGetLastError();
        printf("error = %d\n", error);
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            error,
            MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf,0,NULL);
        std::cout << (LPCTSTR)lpMsgBuf << std::endl;
        LocalFree(lpMsgBuf);
}

IPHeader* sniff(SOCKET sock)
{
    IPHeader *hdr;
    char buffer[MAX_PACKET_SIZE];
    int count = 0;

    count = recv(sock, buffer, sizeof(buffer), 0);
    if (count >= (int)sizeof(IPHeader))
    {
        hdr = (IPHeader *)malloc(MAX_PACKET_SIZE);
        memcpy(hdr, buffer, MAX_PACKET_SIZE);
        return hdr;
    }
    else
        return 0;
}

int main()
{
        WSADATA wsaData;
        char hostname[128];
        HOSTENT* hostinfo;
        SOCKADDR_IN sa;
        sockaddr_in local_addr;
        unsigned long flag = 1;

        if(WSAStartup(0x0202, &wsaData)){ ShowError(); }
        else
        {
                std::cout << "WSAStartup - OK" << std::endl;
                SOCKET sock;
                sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);    // Create raw socket
                if(sock == INVALID_SOCKET){ ShowError(); }
                {
                        std::cout << "Raw scoket is created" << std::endl;
                        //if(closesocket(sock) == SOCKET_ERROR) { ShowError(); }
                }


                gethostname(hostname, sizeof(hostname));
                hostinfo = gethostbyname(hostname);

                ZeroMemory(&sa, sizeof(sockaddr));
                sa.sin_family = AF_INET;
                sa.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr_list[0])->s_addr;

                ZeroMemory(&local_addr, sizeof(local_addr));
                local_addr.sin_family=AF_INET;
                local_addr.sin_addr.s_addr=((struct in_addr *)hostinfo->h_addr_list[0])->s_addr;
                if (bind(sock, (sockaddr *)&local_addr, sizeof(sockaddr) == SOCKET_ERROR))
                {
                    ShowError();
                }

                ioctlsocket(sock, SIO_RCVALL, &flag);

                // Analyze packets
                while (true)
                {
                        IPHeader* hdr = sniff(sock);
                        // обработка IP-пакета
                        if (hdr)
                        { 
                                unsigned char *byte_iterator = (unsigned char *)hdr;
                                for (int i = 0; i < sizeof(IPHeader); i++)
                                {
                                        printf("%02x", *byte_iterator);
                                        ++byte_iterator;
                                }
                        }
                        free(hdr);
                }
                
                if(WSACleanup()) { ShowError(); }
                else
                { std::cout << "WSACleanup - OK" << std::endl;}
        }
        
        return 0;
}

PM MAIL   Вверх
Aoizora
Дата 27.11.2016, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 18.11.2016

Репутация: нет
Всего: нет



Одну проблему решил: не хватало закрывающей скобки. Каким образом из полученных данных можно извлечь данные и распечатать, а не выводить заголовок?

Для переделывания под IPv6, так понимаю, достаточно заменить структуру IP-пакета?

Код

#include <Winsock2.h>
#include <Windows.h>
#include <iostream>

#pragma comment(lib, "Ws2_32.lib")

#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000

typedef struct tagIPHeader
{
  unsigned char  ver_len;        // версия и длина заголовка
  unsigned char  tos;            // тип сервиса 
  unsigned short length;        // длина всего пакета 
  unsigned short id;            // Id 
  unsigned short flgs_offset;        // флаги и смещение
  unsigned char  ttl;            // время жизни 
  unsigned char  protocol;        // протокол 
  unsigned short xsum;            // контрольная сумма 
  unsigned long  src;            // IP-адрес отправителя 
  unsigned long  dest;            // IP-адрес назначения 
  unsigned short *params;        // параметры (до 320 бит)
  unsigned char  *data;            // данные (до 65535 октетов)
} IPHeader;

void ShowError()
{
        LPVOID lpMsgBuf = NULL;
        int error = WSAGetLastError();
        printf("error = %d\n", error);
        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            error,
            MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
            (LPTSTR)&lpMsgBuf,0,NULL);
        std::cout << (LPCTSTR)lpMsgBuf << std::endl;
        LocalFree(lpMsgBuf);
}

IPHeader* sniff(SOCKET sock)
{
    IPHeader *hdr;
    char buffer[MAX_PACKET_SIZE];
    int count = 0;

    count = recv(sock, buffer, sizeof(buffer), 0);
    if (count >= (int)sizeof(IPHeader))
    {
        hdr = (IPHeader *)malloc(MAX_PACKET_SIZE);
        memcpy(hdr, buffer, MAX_PACKET_SIZE);
        return hdr;
    }
    else
        return 0;
}

int main()
{
        WSADATA wsaData;
        char hostname[128];
        HOSTENT* hostinfo;
        SOCKADDR_IN sa;
        sockaddr_in local_addr;
        unsigned long flag = 1;

        if(WSAStartup(0x0202, &wsaData)){ ShowError(); }
        else
        {
                std::cout << "WSAStartup - OK" << std::endl;
                SOCKET sock;
                sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);    // Create raw socket
                if(sock == INVALID_SOCKET){ ShowError(); }
                {
                        std::cout << "Raw scoket is created" << std::endl;
                        //if(closesocket(sock) == SOCKET_ERROR) { ShowError(); }
                }


                gethostname(hostname, sizeof(hostname));
                hostinfo = gethostbyname(hostname);

                ZeroMemory(&sa, sizeof(sockaddr));
                sa.sin_family = AF_INET;
                sa.sin_addr.s_addr = ((struct in_addr *)hostinfo->h_addr_list[0])->s_addr;

                local_addr.sin_family = AF_INET;
                local_addr.sin_port = htons(666);
                local_addr.sin_addr.s_addr = 0;
                if (bind(sock, (sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR)
                {
                    ShowError();
                }

                ioctlsocket(sock, SIO_RCVALL, &flag);

                // Analyze packets
                while (true)
                {
                        IPHeader* hdr = sniff(sock);
                        // обработка IP-пакета
                        if (hdr)
                        { 
                                unsigned char *byte_iterator = (unsigned char *)hdr;
                                for (int i = 0; i < sizeof(IPHeader); i++)
                                {
                                        printf("%c ", *byte_iterator);
                                        ++byte_iterator;
                                }
                        }
                        free(hdr);
                }
                
                if(WSACleanup()) { ShowError(); }
                else
                { std::cout << "WSACleanup - OK" << std::endl;}
        }
        
        return 0;
}


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1122 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.