[Network] Простой ICMP запрос
Всем привет. Начнем потихоньку? Вот [1] пример функции, которая отправляет 4 ICMP запроса (raw-сокет). В качестве аргумента передаем ей строку с IP адресом. Если получено больше одного ответа, то функция возвращает положительный ответ. Предпологается, что функция используется по аналогии с ping(8). Кто что думает об этом коде? Что можно улучшить? Мне вот интересно, сколько по-вашему стоит получить ответов, чтобы быть уверенным, что сеть работет без проблем и задержка с ответами не слишком большая? Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root? Alex [1] http://goo.gl/2eAH4C
На всякий случай отстальная часть кода (к логике работы самого icmp не относится). #include <error.h> #include <fcntl.h> #include <unistd.h> #include <sys/types.h> #include <sys/utsname.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <resolv.h> #include <netinet/ip_icmp.h> #define PACKETSIZE 64 void usage() { printf("USAGE:\t prog_name <IP_address>\n"); exit(1); } int main(int argc, char *argv[]) { if(argv[1] == NULL) usage(); if (ping(argv[1]) > 0) printf("PING\t\tOK\n"); else printf("PING\t\tNO_ANSWER\n"); return 0; } 2014-11-21 14:15 GMT+01:00 Alex Naumov <alexander_naumov@opensuse.org>:
Всем привет.
Начнем потихоньку? Вот [1] пример функции, которая отправляет 4 ICMP запроса (raw-сокет). В качестве аргумента передаем ей строку с IP адресом. Если получено больше одного ответа, то функция возвращает положительный ответ. Предпологается, что функция используется по аналогии с ping(8).
Кто что думает об этом коде? Что можно улучшить?
Мне вот интересно, сколько по-вашему стоит получить ответов, чтобы быть уверенным, что сеть работет без проблем и задержка с ответами не слишком большая?
Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root?
Alex
думаю, что сеть можно считать рабочей, если вернулось не меньше 3-х из 4-х пакетов, еще я бы проверил контрольную сумму принятого пакета, без нее как-то не кошерно, еще я не очень понял, recvfrom не блокируется в ожидании ответа? получается, что как минимум первый вызов recvfrom всегда пройдет в холостую, я бы возможно попробовал отдельный сделать поток для посылки пингов и отдельный поток для приема пакетов, возврат из потока я не очень понимаю, как делать, так что сделал бы внешнюю переменную, в которой бы записывалось кол-во принятых пакетов, при этом вызов recvfrom сделал бы блокирующимся, но я не знаю как это делать, по идее он по умолчанию такой, иначе придется делать холостой цикл, который будет отъедать процессорное время. 21.11.14, Alex Naumov<alexander_naumov@opensuse.org> написал(а):
Всем привет.
Начнем потихоньку? Вот [1] пример функции, которая отправляет 4 ICMP запроса (raw-сокет). В качестве аргумента передаем ей строку с IP адресом. Если получено больше одного ответа, то функция возвращает положительный ответ. Предпологается, что функция используется по аналогии с ping(8).
Кто что думает об этом коде? Что можно улучшить?
Мне вот интересно, сколько по-вашему стоит получить ответов, чтобы быть уверенным, что сеть работет без проблем и задержка с ответами не слишком большая?
Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root?
Alex
сегодня что-то делать уже не хочется, завтра могу переписать с использованием 2-х разных потоков. 22.11.14, Ivan Riabtsov<ivriabtsov@gmail.com> написал(а):
думаю, что сеть можно считать рабочей, если вернулось не меньше 3-х из 4-х пакетов, еще я бы проверил контрольную сумму принятого пакета, без нее как-то не кошерно, еще я не очень понял, recvfrom не блокируется в ожидании ответа? получается, что как минимум первый вызов recvfrom всегда пройдет в холостую, я бы возможно попробовал отдельный сделать поток для посылки пингов и отдельный поток для приема пакетов, возврат из потока я не очень понимаю, как делать, так что сделал бы внешнюю переменную, в которой бы записывалось кол-во принятых пакетов, при этом вызов recvfrom сделал бы блокирующимся, но я не знаю как это делать, по идее он по умолчанию такой, иначе придется делать холостой цикл, который будет отъедать процессорное время.
21.11.14, Alex Naumov<alexander_naumov@opensuse.org> написал(а):
Всем привет.
Начнем потихоньку? Вот [1] пример функции, которая отправляет 4 ICMP запроса (raw-сокет). В качестве аргумента передаем ей строку с IP адресом. Если получено больше одного ответа, то функция возвращает положительный ответ. Предпологается, что функция используется по аналогии с ping(8).
Кто что думает об этом коде? Что можно улучшить?
Мне вот интересно, сколько по-вашему стоит получить ответов, чтобы быть уверенным, что сеть работет без проблем и задержка с ответами не слишком большая?
Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root?
Alex
2014-11-21 22:16 GMT+01:00 Ivan Riabtsov <ivriabtsov@gmail.com>:
думаю, что сеть можно считать рабочей, если вернулось не меньше 3-х из 4-х пакетов,
Да, 75% конечно надежней, чем 50%, но если мы получили хотя бы... даже один ответ, значит хост работает и отвечат. По количеству отстальных ответов можно судить о качестве соединения.
еще я бы проверил контрольную сумму принятого пакета, без нее как-то не кошерно
Да, она добавляется, но не проверяется при получении. Значит ли это, что, если я ping'ую два хоста, то ответы могут просто перемешаться?
еще я не очень понял, recvfrom не блокируется в ожидании ответа?
Я просто добавил пока секундную задержку :) Кстати, не подвесит ли блокировка процесс, при отсутствии ответов?
получается, что как минимум первый вызов recvfrom всегда пройдет в холостую,
Да, сам не знаю как так получилось - конечно же recvfrom() и sendto() надо поменять местами.
я бы возможно попробовал отдельный сделать поток для посылки пингов и отдельный поток для приема пакетов, возврат из потока я не очень понимаю, как делать, так что сделал бы внешнюю переменную, в которой бы записывалось кол-во принятых пакетов, при этом вызов recvfrom сделал бы блокирующимся, но я не знаю как это делать, по идее он по умолчанию такой, иначе придется делать холостой цикл, который будет отъедать процессорное время.
Будет интересно посмотреть на код, но на сколько оправданно распараллеливание потока (т.е. усложнение кода) в данном случае?
Привет Alex. Может имеет смысл создать репозиторий на github или еще где. Что б можно было сразу примеры-задачки сливать, собирать, вносить правки. Я это предлагаю в контексте
Кто что думает об этом коде? Что можно улучшить? Что б можно было создавать бранчи с решениям, которые по мнению конкретного взятого разработчика улучшают код. И затем обсуждать. И всегда можно будет в переписке ссылаться на нужный коммит/ветку. Это только предложение. А не условие.
Анализируя пристегнутый код письму могу только пока предложить вариант ответа к следующему вопросу
Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root? Тут я немного схитрил, что б получить ответ. Рута запрашивает на sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
А стандартный системный ping - нет. Поэтому не долго думая, слил исходники пакета busybox (очень советую скачать всем, кто хочет в полной мере на примере изучать разработку системного ПО) и начал сравнивать нашей реализации Ping с тем что представлено в нем. Сокет создается там примерно так же. Но идет проверка, что если сокет не создался, то идет проверка на права доступа со следующей припиской. /* We don't have root privileges. Try SOCK_DGRAM instead.// // * Linux needs net.ipv4.ping_group_range for this to work.// // * MacOSX allows ICMP_ECHO, ICMP_TSTAMP or ICMP_MASKREQ// // */// /Гугл по запросу /ping_group_range Выдал такой результат. / Socket(2) is restricted to the group range specified in "/proc/sys/net/ipv4/ping_group_range" (or the owner of CAP_NET_RAW). It is "1 0" by default, meaning that nobody except root may create ping sockets. Setting it to "100 100" would gain permissions to the single group, "0 65535" would enable it for the world. P.S. Я тут пытаюсь освоить/вспомнить работу с рассылкой. Поэтому допускаю, что от меня ближайшее время заспамит одним и тем же сообщением по разным адресам. Прошу прощения за это заранее. 21.11.2014 16:15, Alex Naumov пишет:
Всем привет.
Начнем потихоньку? Вот [1] пример функции, которая отправляет 4 ICMP запроса (raw-сокет). В качестве аргумента передаем ей строку с IP адресом. Если получено больше одного ответа, то функция возвращает положительный ответ. Предпологается, что функция используется по аналогии с ping(8).
Кто что думает об этом коде? Что можно улучшить?
Мне вот интересно, сколько по-вашему стоит получить ответов, чтобы быть уверенным, что сеть работет без проблем и задержка с ответами не слишком большая?
Кто-нибудь может ясно объяснить, почему для корректной работы он требует права root?
Alex
[1]http://goo.gl/2eAH4C <http://goo.gl/2eAH4C>
_______________________________________________ Kernel-russian mailing list Kernel-russian@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernel-russian
participants (3)
-
Alex Naumov -
Ivan Riabtsov -
Naydin Andrey