Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Перехват данных по локальной сети ?


Автор: Guest_shedon 6.5.2003, 07:33
Есть небольшой код который ловит IP пакеты и читает их заголовки:
Код

typedef struct IPHeader {
 UCHAR   iph_verlen;   // версия и длина заголовка
 UCHAR   iph_tos;      // тип сервиса
 USHORT  iph_length;   // длина всего пакета
 USHORT  iph_id;       // Идентификация
 USHORT  iph_offset;   // флаги и смещения
 UCHAR   iph_ttl;      // время жизни пакета
 UCHAR   iph_protocol; // протокол
 USHORT  iph_xsum;     // контрольная сумма
 ULONG   iph_src;      // IP-адрес отправителя
 ULONG   iph_dest;     // IP-адрес назначения
} IPHeader;

recv( s, Buffer, sizeof(Buffer), 0 );

IPHeader* hdr = (IPHeader *)Buffer;


Как прочитать сам пакет ? И узнать порт по которому он шел ?
(Используется winsock2)

Автор: DarkDS 6.5.2003, 12:01
У тебя есть длинна и смещение... вот и считываешь по этим данным пакет после заголовка...
Почитай доки по протоколам на досуге...

Автор: Step 6.5.2003, 13:50
ответ как всегда прост.
другими словами прочитай заголовок, определи длину, и прочитай еще в буффер пакет длиной которую определил

Автор: DarkDS 6.5.2003, 14:19
Кстати... Флаги и смешения (iph_offset) там не просто так:
Поле Флаги указывает на факт фрагментации пакета, а также на наличие или отсутствие последующих пакетов при фрагментации.
Поле Смещение фрагмента используется для указания в байтах смещения поля данных этого пакета от начала общего поля данных исходного пакета, подвергнутого фрагментации. Используется при сборке/разборке фрагментов пакетов при передачах их между сетями с различными величинами максимальной длины пакета.

Получить порт можно разшифровав тело пакета:
Надеюсь ты знаешь технологию передачи пакетов? но на всякий случай скажу, что в пакете протокола IP будет лежать еще один пакет - протокола ТCP, а в нем лежт пакет высокого уровня... кстати тип последнего пакета указывается полем протокол (iph_protocol)...
Так вот порт указывается как раз в пакете ТСП или выше, зависит от ситуации...

Автор: DarkDS 6.5.2003, 14:23
Сорри Запамятовал... в пакете ИП может лежать либо ТСП, ЛИБО UDP протоколы... Порт чаще всего пишется в них...
Вот такая вот загагулина!

В общем почитай книжки по протоколам... помогает smile.gif

Автор: Guest_Shedon 7.5.2003, 08:18
А можно както конкретно определить где лежит порт, зная протокол ?

Автор: AntonSaburov 7.5.2003, 08:33
Цитата
А можно както конкретно определить где лежит порт, зная протокол ?


Что значит "конкретно" - заголовок TCP является стандартным и у него на определенном месте стоит номер порта. Точное местоположение я не вспомню - надо смотреть документацию. Те же RFC.

Автор: Guest_Shedon 7.5.2003, 09:03
У меня почемуто неправильновычисляется размер заголовка, почти всегда кажет "69". Возможно с "iph_verlen", надо провести какието преобразования ?

Автор: DarkDS 7.5.2003, 11:19
Все поясняется очень просто - старшие пол байта (4 бита) есть длинна заголовка... Младшие 4 - это версия протокола...
То есть чтобы получить истинную длинну протокола тебе нужно взять старшие 4 бита... самый просто способ - сдвиг в право на 4 бита smile.gif

Автор: Guest_Shedon 7.5.2003, 15:32
Он всегда показывает 4 байта

Автор: DarkDS 7.5.2003, 15:54
Цитата(Guest_Shedon @ 7.5.2003, 15:32)
Он всегда показывает 4 байта

Какие 4 байтаconfused.gif
UCHAR iph_verlen;
если мне еще не изменяет память (а она мне врядли изменяет) UCHAR - это беззнакомый чар размер - 1 байт.
Из этого байта 4 бита - версия, 4 бита - длинаа.
Вот к примру чило 69. если брать по битам то это 01000101 соответсвенно разобьются на 0100 и 0101.
Старшие биты (7-4) = 0100 есть длинна загововка... младшие(3-0) 0101 - версия...

Автор: DarkDS 7.5.2003, 15:55
Или ты имеешь ввиду что всегда приходит 0100?

ЗЫ. Забыл сказать - длина заголовка измеряется в 4-х байтных словах smile.gif

Автор: Guest_Shedon 8.5.2003, 07:25
Всё понётно я просто не вту сторону смещал, и получается 5, тоесть 20 байт.

Автор: DarkDS 8.5.2003, 11:48
ЗЫ... Кстати... Длинна пакета исчесляется с учетом заголовка.
Смещение используется только тогда, когда происходит фрагментация пакета. Смешение указывает на позицию данных, относительно начала (данных). Так же смещение всегда (кроме последнего пакета) должно быть кратно 8... Правда чаще всего смещение не используется, так как протокол ТСП при отсылке пакетов посылает их нужного размера... smile.gif то есть ИП не нада разбивать... Проверить на фрагментацию данных можно так: (0x2000&iph_offset) != 0 ( 0x2000 - флаг фрагментации, 0x4000 - флаг нефрагментированности, 0x8000 - зарезервирован, всегда должен быть 0 (иначе - ошибка заголовка) )
О iph_xsum объяснения нужны? smile.gif

Автор: Step 14.5.2003, 16:52
а как указать сокет, что бы перехватывало все пакеты

Автор: DarkDS 14.5.2003, 17:00
Цитата(Step @ 14.5.2003, 16:52)
а как указать сокет, что бы перехватывало все пакеты

То есть? smile.gif

Автор: Step 14.5.2003, 17:04
recv( s, Buffer, sizeof(Buffer), 0 );


первый параметр это переменная типа сокет


какой сокет нужно указать что бы перехватывались все покеты которые приходят

Автор: DarkDS 14.5.2003, 19:48
Ниже приведенный код чесно стырен smile.gif Но он описывает работу сниффера smile.gif
Код

#include <conio.h>
#include <winsock2.h>

#define MAX_PACKET_SIZE    0x10000
// Буфер для приёма данных
static BYTE Buffer[MAX_PACKET_SIZE]; // 64 Kb

void main()
{
 WSADATA     wsadata;   // Инициализация WinSock.
 SOCKET      s;         // Cлущающий сокет.
 char        name[128]; // Имя хоста (компьютера).
 HOSTENT*    phe;       // Информация о хосте.
 SOCKADDR_IN sa;        // Адрес хоста
 long        flag = 1;  // Флаг PROMISC Вкл/выкл.

 // инициализация
 WSAStartup(MAKEWORD(2,2), &wsadata);
 s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
 gethostname(name, sizeof(name));
 phe = gethostbyname( name );
 ZeroMemory( &sa, sizeof(sa) );
 sa.sin_family = AF_INET;
 sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
 bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
 
 // Включение promiscuous mode.
 ioctlsocket(s, SIO_RCVALL, &flag);

 // Приём IP-пакетов.
 while( !_kbhit() )
 {
   int count;
   count = recv( s, Buffer, sizeof(Buffer), 0 );
   // обработка IP-пакета
   if( count >= sizeof(IPHeader) )
   {
     IPHeader* hdr = (IPHeader *)Buffer;
     //что-то делаем с пакетом...
   }
 }
 // Конец работы.
 closesocket( s );
 WSACleanup();
}

Автор: DarkDS 14.5.2003, 19:57
http://www.komodia.com/tools.htm
Тут есть уже работающий сниффер smile.gif

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)