Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 27.11.2016, 18:31   #1
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию Получить данные из IP-пакета

Пишу небольшой анализатор IP-пакетов, который перехватывает пакеты и выполняет над ними некоторые действия. Я определил структуры для IP-заголовка и для всего пакета в целом. Структура пакета состоит из IP-заголовка и массива данных. Пакет из процедуры sniff возвращается, вроде бы, корректный, во всяком случае адреса отправителя и получателя похожи на настоящие. Проблема с анализом данных.

Как определить размер этих данных?
Этот размер я сейчас вычисляю как разность между значением поля IPHeader.length и размером IP-заголовка. Однако при выводе на экран такого количества байт из массива IPPacket.data выводится много мусора. Как точно определить размер данных? Правильно ли я сохраняю эти данные в структуре и обращаюсь к ним?

Еще я хочу убедиться в корректности принятых данных. По каким сигнатурам можно это сделать? В PE-файлах есть сигнатуры MZ и PE, а в IP-пакетах есть, вроде бы, поля с версией TCP-протокола. Какие смещения у этих полей?

Код:
#include <Winsock2.h>
#include <Windows.h>
#include <iostream>

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

#define SIO_RCVALL 0x98000001
#define MAX_PACKET_SIZE 0x10000

// Структура IP-заголовка
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 бит)
} IPHeader;

// Структура IP-пакета, состоящая из заголовка и данных
typedef struct tagIPPacket
{
	IPHeader header;
	char data[65515];
} IPPacket;


// Форматированный вывод сообщения об ошибке
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);
}

// Перехват IP-пакетов
IPPacket* sniff(SOCKET sock)
{
	IPPacket *packet;
	char buffer[sizeof(IPPacket)];
	int count = 0;

	count = recv(sock, (char *)&buffer, sizeof(buffer), 0);
	if (count >= (int)sizeof(IPHeader))
	{
		packet = (IPPacket *)malloc(sizeof(IPPacket));
		memcpy(packet, (char *)&buffer, sizeof(IPPacket));
		return packet;
	}
	else
		return 0;
}

// Печать полей IP-заголовка
void ShowIPFields(IPHeader *hdr)
{
	printf("version and length: %u\n", hdr->ver_len);
	printf("type of service %u\n", hdr->tos);
	printf("length of packet: %hu\n", hdr->length);
	printf("id = %hu\n", hdr->id);
	printf("flags and offset: %hu\n", hdr->flgs_offset);
	printf("ttl = %u\n", hdr->ttl);
	printf("protocol = %u\n", hdr->protocol);
	printf("crc32: %hu\n", hdr->xsum);
	printf("src = %u.%u.%u.%u\n", hdr->src & 0xFF, (hdr->src & 0xFF00) >> 8, (hdr->src & 0xFF0000) >> 16, (hdr->src & 0xFF000000) >> 24);
	printf("dst = %u.%u.%u.%u\n", hdr->dest & 0xFF, (hdr->dest & 0xFF00) >> 8, (hdr->dest & 0xFF0000) >> 16, (hdr->dest & 0xFF000000) >> 24);
}

// Вывод на экран полей заголовка и данных
void ShowIPPacket(IPPacket *packet)
{
	printf("IP Header:\n");
	ShowIPFields(&packet->header);

	// Print data
	printf("\n IP Data:\n");
	for (int i = 0; i < packet->header.length - sizeof(IPHeader); i++)
	{
		/*if (i % 15 != 0)
		{
			printf("%02x ", packet->data[i]);
		}
		else printf("\n");*/
	}
}

// Действия над перехваченным пакетом
void AnalyzePacket(IPPacket *packet)
{
	ShowIPPacket(packet);
	printf("\n\n");
}

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;

				if (bind(sock, (sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR)
				{
					ShowError();
				}

				ioctlsocket(sock, SIO_RCVALL, &flag);

				// Analyze packets
				while (true)
				{
						IPPacket *packet = sniff(sock);
						// обработка IP-пакета
						if (packet)
						{ 
								AnalyzePacket(packet);
						}
						free(packet);
				}
                
                if(WSACleanup()) { ShowError(); }
                else
				{ std::cout << "WSACleanup - OK" << std::endl;}
        }
        
        return 0;
}
Aoizora вне форума Ответить с цитированием
Старый 27.11.2016, 18:32   #2
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Вот как выглядит распечатывание IP-заголовков.
Изображения
Тип файла: png ip.png (12.1 Кб, 225 просмотров)
Aoizora вне форума Ответить с цитированием
Старый 27.11.2016, 18:38   #3
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Ограничил число выводимых байт данных 100.
Все равно выводится мусор, но иногда печатается что-то похожее на корректные данные.
Изображения
Тип файла: png ip.png (11.8 Кб, 187 просмотров)
Aoizora вне форума Ответить с цитированием
Старый 27.11.2016, 18:52   #4
Aoizora
Заблокирован
 
Регистрация: 11.11.2016
Сообщений: 261
По умолчанию

Прикрутил 16ричный дамп буфера. Видел в дампе HTTP-запросы, то есть в packet->data действительно данные.
Изображения
Тип файла: png ip.png (8.3 Кб, 188 просмотров)
Aoizora вне форума Ответить с цитированием
Старый 22.02.2017, 17:54   #5
АндрейЙя
 
Регистрация: 22.08.2016
Сообщений: 5
По умолчанию

Блин, а Вы на заказ делаете? Мне необходимо выполнить подобного рода работу на производстве: https://www.konsom.ru/solutions/info...i-dannyh-tsod/ вот пытаюсь найти специалиста.
АндрейЙя вне форума Ответить с цитированием
Старый 22.02.2017, 18:16   #6
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Зачем придумывать свои определения заголовков, если они уже определены?
p51x на форуме Ответить с цитированием
Старый 02.03.2017, 13:29   #7
АндрейЙя
 
Регистрация: 22.08.2016
Сообщений: 5
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Зачем придумывать свои определения заголовков, если они уже определены?
Девиз у Вас отличный в подписе!)
АндрейЙя вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Получить данные из Frame Shouldercannon Общие вопросы Delphi 4 24.11.2017 23:15
Получить данные с curl rustrek PHP 1 10.01.2016 02:57
получить данные с бд megostudent БД в Delphi 5 14.05.2013 11:30
получить данные из Warcraft 3 frantic150 Общие вопросы C/C++ 8 09.06.2011 18:53
Получить данные из WMF AnTe Мультимедиа в Delphi 0 18.01.2011 08:14