Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Пример простейшего сниффера для W2K/XP

Ниже приведён полный код программы. Данный код не претендует на звание крутого снифера, однако при желании его можно доработать, чтобы можно было просматривать содержимое пакетов. Так же на его основе можно легко сделать простой анализатор трафика. А главное - не надо делать всяких драйверов; всё просто и понятно.

Суть этого сниффера заключается в том, что используются сокеты второй версии и созданный сокет переводится в режим promiscuous (прослушивания).

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

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

//Структура заголовка 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;

char src[10];
char dest[10];
char ds[15];
unsigned short lowbyte;
unsigned short hibyte;

void main()
{
  WSADATA     wsadata;   // Инициализация WinSock.
  SOCKET      s;         // Cлущающий сокет.
  char        name[128]; // Имя хоста (компьютера).
  HOSTENT*    phe;       // Информация о хосте.
  SOCKADDR_IN sa;        // Адрес хоста
  IN_ADDR sa1;        //
  unsigned 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;
      //Начинаем разбор пакета...

	strcpy(src,"Пакет: ");
	CharToOem(src,dest);
	printf(dest);
	// Преобразуем в понятный вид адрес отправителя.
	printf("From ");
	sa1.s_addr = hdr->iph_src;
	printf(inet_ntoa(sa1));

	// Преобразуем в понятный вид адрес получателя.
	printf(" To ");
	sa1.s_addr = hdr->iph_dest;
	printf(inet_ntoa(sa1));

	// Вычисляем протокол. Полный список этих констант
	// содержится в файле winsock2.h
	printf(" Prot: ");
	if(hdr->iph_protocol == IPPROTO_TCP) printf("TCP ");
	if(hdr->iph_protocol == IPPROTO_UDP) printf("UDP ");

	// Вычисляем размер. Так как в сети принят прямой порядок
	// байтов, а не обратный, то прийдётся поменять байты местами.
	printf("Size: ");
	lowbyte = hdr->iph_length>>8;
	hibyte = hdr->iph_length<<8;
	hibyte = hibyte + lowbyte;
	printf("%s",itoa(hibyte,"",10));

	// Вычисляем время жизни пакета.
	printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));
	printf("\n");

    }
  }

  closesocket( s );
  WSACleanup();
}

Для успешной компиляции, необходимо подключить к проекту файл ws2_32.lib.

Оригинал статьи: rsdn.ru

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
69K
28 марта 2011 года
Lestat90
3 / / 28.03.2011
Мне нравитсяМне не нравится
28 марта 2011, 22:18:41
попробывал написать ету прогу, запускаеться, но только черный екран, в чем дело, подскажите пожалуйста
2.
13K
19 июля 2006 года
Mad Kit
18 / / 19.07.2006
Мне нравитсяМне не нравится
19 июля 2006, 00:16:47
#define SIO_RCVALL 0x98000001
Люди, помогите плз. Обьясните по каким принципам взято число 0x98000001? Как его получили?


3.
Аноним
Мне нравитсяМне не нравится
30 мая 2006, 23:29:05
printf("%s",itoa(hibyte,"",10));
printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));

В функциях "intoa" вместо ковычек надо поставить ds, то есть:

printf("%s",itoa(hibyte,ds,10));
printf(" TTL:%s",itoa(hdr->iph_ttl,ds,10));

p.s. иначе ds нигде не используется... ;)
И все будет!

4.
Аноним
Мне нравитсяМне не нравится
31 мая 2005, 12:10:52
А что за _kbhit()? У меня все компиляторы ругаются. (((
5.
Аноним
Мне нравитсяМне не нравится
11 мая 2005, 16:08:56
Джентльмены !!! А можно ли сделать похожую штучку чтобы работать с пакетом Ethernet и иметь к нему доступ - передавать и принимать произвольные данные ???
6.
Аноним
Мне нравитсяМне не нравится
6 апреля 2005, 13:41:52
2Иван
пользуй библиотеку WinPCAP (Windows Packet Capture Library). на ней, например, Ethereal написан.
7.
Аноним
Мне нравитсяМне не нравится
23 февраля 2005, 16:15:21
А как насчет исходящих???
8.
Аноним
Мне нравитсяМне не нравится
22 февраля 2005, 01:25:25
Эта штучка слушает только входящие пакеты?
9.
Аноним
Мне нравитсяМне не нравится
17 ноября 2004, 14:18:47
Ну я просто ща лопну со смеха!
нафига писать printf("%s",itoa(hibyte,"",10));
если можно просто printf("%u", hibyte); ???????
к тому же это все рухнет, ведь destination string для itoa() - строка НУЛЕВОЙ длины!!! А теперь подумайте куда запишется результат...
10.
Аноним
Мне нравитсяМне не нравится
13 октября 2004, 21:39:15
Правильно ли я понял, что Winsock API позволит таким образом увидеть только IP-датаграммы? Если да, то можно ли и как получить доступ к всему Ethernet-кадру?
11.
Аноним
Мне нравитсяМне не нравится
8 сентября 2004, 12:57:15
он не будет работать!!! :))) надо изменить строки:
printf("%s",itoa(hibyte,"",10));
printf(" TTL:%s",itoa(hdr->iph_ttl,"",10));
после этого работать будет
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог