Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: RAW Sockets / ICMP  (Прочитано 13394 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Robin Hood PHD
Гость
« : 04-03-2008 18:03 » 

Доброго времени суток, товарищи!

Решил я в целях самообучения поюзать сырые сокеты. Решил сделать простенькую консольную програмку, смысл которой ждать прихода ICMP пакета (пинга) и когда он придет, напечатать IP приславшего пакет и его размер. (код в конце поста)

Проблема в следующем...Когда я отсылаю пакет себе (ping 127.0.0.1) все прекрасно работает, но вот если меня пингует удаленный компьютер ничего не выходит - программа так и висит на recvfrom ожидая маны небесной.

Есть вариант, что мешает антивирь - у меня стоит Панда с интегрированным фаерволлом...возможно такое?
Есть у кого нб какие либо соображения на этот счет?

Заранее благодарен!

Привожу код:

Код:
// Программа называется "попингуй" )
#include "stdio.h"
#include "winsock2.h"
#include "windows.h"

int main(int argc, char* argv[])
{
WSADATA wsd;
if (WSAStartup (MAKEWORD (2,2), &wsd) != 0) {
printf ("Error WSA init\n");
return 0;
}
   SOCKET sc;
   SOCKADDR_IN addr;
   char buf [1024];
   int len;
   int fromlen;
   int res;
   fromlen = sizeof (addr);
   len = sizeof (buf);

LPPROTOENT lpProtocolEntry;
int nProtocol;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);

   if ((lpProtocolEntry = getprotobyname("icmp")) == NULL)
   nProtocol = IPPROTO_ICMP;
   else
   nProtocol = lpProtocolEntry->p_proto;

   sc = socket(AF_INET, SOCK_RAW, nProtocol);

if (sc == INVALID_SOCKET) printf ("INVALID SOCKET!");   
if (bind (sc,(LPSOCKADDR) &addr,sizeof (addr)) != 0) printf ("CAN'T BIND!");

   res = recvfrom (sc,buf,len,0,(LPSOCKADDR) &addr,&fromlen);
   if (res == SOCKET_ERROR) {
      printf ("An error! %d \n",GetLastError ());
   }
   else {
   printf ("Length: %d\n",fromlen);
   printf ("IP: %s\n", (LPSTR) inet_ntoa (addr.sin_addr) );
   printf ("Msg: %s\n",buf);
   MessageBox (0,"","",0);
   }
   return 0;
}
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 04-03-2008 18:40 » 

Robin Hood PHD, как это вообще скомпилировалось? Типы socket и sockaddr_in пишутся маленькими буквами!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #2 : 04-03-2008 18:44 » new

Вот тут https://forum.shelek.ru/index.php/topic,9206.0.html я скидывал программу ping на ICMP сокетах. Пример правда написан под Linux, но в винду перевести можно.
1. Зачем делать bind. Эта команда привязывает сокет к порту. ICMP вообше не имеют портов, по своему определению.
2. После окончания работы с сокетами, их нужно обязательно закрыть.
« Последнее редактирование: 04-03-2008 18:49 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Robin Hood PHD
Гость
« Ответ #3 : 04-03-2008 18:51 » 

Robin Hood PHD, как это вообще скомпилировалось? Типы socket и sockaddr_in пишутся маленькими буквами!

M$ Visual C++ 6.0 это схавал...думаю моя проблема не в этом.
Finch, спасибо, вроде то, что нужно...

А хотя бы теоретически, способен фаерволл помешать программе запусщенной на том же компе обрабатывать ICMP пакеты?
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 04-03-2008 18:53 » 

Вполне.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 04-03-2008 19:48 » 

а кто отвечает на пинг?
Если с удаленный комп пингует и получает ответы, то файрвол здесь ни причем
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #6 : 04-03-2008 20:07 » 

Sla, В ICMP нету понятия портов, поэтому все пакеты рассылаются абсолютно всем подписавшимся сокетам на данном компе. Теперь если ты его с удаленного компа пингуеш, то должен прийти также пакет и в данную программу. Если пакеты не доходят, то они или вообше не приходят на комп, или фильтруются на более нижнем этапе.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Robin Hood PHD
Гость
« Ответ #7 : 04-03-2008 20:30 » 

Вроде заработало... Вот только я не совсем понимаю один момент. Программа должна выводить IP пославшего пакет
printf ("IP: %s\n", (LPSTR) inet_ntoa (addr.sin_addr) );
Меня пингует человек с известным мне IP и отправляет мне 4 пакета. Моя программа их ловит, но вот почему то IP выводятся РАЗНЫЕ, ни один из которых не совпадает с IP моего товарища !? Я что то упустил?
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines