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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Сетевое под UNIX (SOCK_ROW)  (Прочитано 9623 раз)
0 Пользователей и 1 Гость смотрят эту тему.
VackuM
Гость
« : 13-05-2008 13:56 » 

Решил изучать сетевое программ. Взался сразу за SOCK_ROW (захотелось утилиту пинг реалезовать). Даже вродеб как работает, но посмотрел в снифер и непонравилось что я там увидел- контрольная сума для ICMP корректная (функцию где-то здесь нашел), а вот для ip протокола забита нулями(удивился: как мне еще и ответ пришел). Насколько я понимаю ip checksum должна сама рассчитыватся,но видать я ее как-то перезатераю или еще что-то....

Код:
class Net
{
private:

unsigned short checksum(void *b, int len)       
{
unsigned short *buf = (unsigned short *)b, result;
    unsigned int sum=0;
   
for ( sum = 0 ; len > 1 ; len-=2)
{
sum += *buf;   
buf++;
}

    if ( len == 1 )                     
    sum += *(unsigned char*) buf;
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);                                       
    result = ~sum;                         
    return result;           
}

public:
bool Ping(char *host)
{
int sockfd,get;
struct sockaddr_in to;
struct icmp *icmp_h;
short pingLength=1024;
char *buffer= new char [pingLength];

sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

icmp_h = (struct icmp*) buffer;
bzero(icmp_h, sizeof(struct icmp));

icmp_h->icmp_type = ICMP_ECHO;
icmp_h->icmp_code = 0;
icmp_h->icmp_id = rand() % 65535;
icmp_h->icmp_seq = rand() % 65535;
icmp_h->icmp_cksum=checksum(buffer,pingLength);

bzero(&to,sizeof(to));
to.sin_family=AF_INET;
to.sin_addr.s_addr=inet_addr(host);

sendto(sockfd, buffer, pingLength, 0,(struct sockaddr *) &to, sizeof(to));

get=recv(sockfd, buffer, pingLength, 0);

}
};

« Последнее редактирование: 13-05-2008 15:03 от Finch » Записан
Finch
Спокойный
Администратор

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


« Ответ #1 : 13-05-2008 14:58 » 

В учебниках рекомендуют так создавать сокет
1.
Код:
	struct protoent* proto;
proto = getprotobyname("ICMP");
sdin  = socket(PF_INET, SOCK_RAW, proto->p_proto);
2.
Код:
 icmp_h->icmp_id = rand() % 65535;
icmp сообшения идут всем и сразу, нужно как-то распознавать программе, что это именно ее пакет. Поэтому тут рекомендуют ставить id самого процесса. И при приеме сначало смотреть на id пакета, а потом уже обрабатывать.
3. Сокеты нужно обязательно закрывать после использования. Это ресурс системы. Не закрытый сокет влияет на работу полностью на всю систему.

Тут https://forum.shelek.ru/index.php/topic,9206.msg134063#msg134063 я бросал пример пингатора, правда без применения ООП.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
VackuM
Гость
« Ответ #2 : 14-05-2008 08:05 » 

Спасибо за ссылку, будем разбиратся. Вот только напрашивается вопрос, неужели нет некоторого АПИ для icmp протокола, чтоб вызвал одну функцию с основными параметрами icmp протокола и вернуло тебе true or false (есть ответ от хоста или нет). Конечно такой низкоуровневый подход тож интересен но когда времени не слишком много эт не сильно удобно...
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #3 : 14-05-2008 09:20 » 

VackuM, можно воспользоваться библиотекой pcap.
Записан

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

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


« Ответ #4 : 14-05-2008 19:43 » 

ICMP протокол в обычных программах как бы и не нужен. У меня например, чтобы с ним играться, нужно права root.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
VackuM
Гость
« Ответ #5 : 15-05-2008 06:02 » 

Да, даже эти программы с установленым suid битом....  Все таки переводить интерфейс в неблокируемый режим (или неразборчивый режим), тут уж точно нужны права рута...

ls -l /usr/sbin/traceroute
-r-sr-xr-x  1 root  wheel  23404 Apr  9 23:41 /usr/sbin/traceroute
ls -l /sbin/ping
-r-sr-xr-x  1 root  wheel  23872 Apr  9 23:40 /sbin/ping

Но, как нистрано у виндовс вроде б как icmp api есть....
Записан
Finch
Спокойный
Администратор

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


« Ответ #6 : 15-05-2008 19:45 » new

VackuM, Я насколько знаю под C# нету компонент для ICMP протокола, по крайней мере в стандартной поставке .NET. Есть только компоненты для TCP и UDP. 99.9 % апликаций этих двух протоколов достаточно выше крыши.
Кстати, а что тебе не хватает в функциях стандартных сокетов?
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines