Я видел другую программу, предоставляющую в ней функциональность traceroute, но без привилегий root (суперпользователя)? Я всегда предполагал, что необработанные сокеты должны быть корневыми, но есть ли другой способ? (Кажется, кто-то упомянул «supertrace» или «tracepath»?) Спасибо!
Как можно запустить программу, подобную traceroute, без привилегий root?
Ответы (5)
Пропингуйте цель, постепенно увеличивая TTL и наблюдая, откуда берутся ответы «TTL превышен».
Вместо того, чтобы использовать необработанные сокеты, некоторые приложения используют порт tcp или udp с более высоким номером. Направив этот tcp-порт на порт 80 на известном веб-сервере, вы можете проследить маршрут до этого сервера. Недостатком является то, что вам нужно знать, какие порты открыты на целевом устройстве, чтобы подключить его.
ping и traceroute используют протокол ICMP. Подобно UDP и TCP, это доступно через обычный API сокетов. Только номера портов UDP и TCP менее 1024 защищены от использования, кроме как пользователем root. ICMP свободно доступен для всех пользователей.
Если вы действительно хотите увидеть, как работают ping и traceroute, вы можете загрузить пример реализации кода C для них с КодПрожект.
Короче говоря, они просто открывают сокет ICMP, а traceroute изменяет приращение TTL, используя setsockopt, пока цель не будет достигнута.
Вам не нужно использовать необработанные сокеты для отправки и получения пакетов ICMP. По крайней мере, не в Windows.
Если у вас современный дистрибутив Linux, вы можете посмотреть в источнике traceroute (или tracepath, появившийся до того, как traceroute потерял setuid) и tcptraceroute. Ни одному из них не требуются сокеты RAW — проверено на Fedora 9, они не setuid и работают с параметрами по умолчанию для обычного пользователя.
Использование кода, который делает tcptraceroute, может быть esp. полезно, поскольку пакеты ICMP на адрес не обязательно заканчиваются в том же месте, что и TCP-соединение, например, с портом 80.
Выполнение трассировки traceroute (как обычный пользователь) показывает, что он делает что-то вроде:
int opt_on = 1;
int opt_off = 0;
fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &opt_off, sizeof int)
setsockopt(fd, SOL_SOCKET, SO_TIMESTAMP, &opt_on, sizeof int)
setsockopt(fd, SOL_IP, IP_RECVTTL, &opt_on, sizeof int)
...и затем чтение данных из результатов CMSG.