Network - traceroute
Network - traceroute
Команда traceroute(1) в некоторых случаях позволяет выяснить маршрут от одного компьютера до другого. Для этого она посылает пакеты на целевую машину последовательно увеличивая параметр TTL (time to live). В норме TTL должен уменьшаться на единицу на каждом маршрутизаторе, пока не станет равным нулю. Если он обнулится, пакет будет отброшен, а отославшей его стороне вернётся пакет ICMP TIME_EXCEEDED. В этом пакете будет присутствовать IP маршрутизатора, который его послал. По этой информации traceroute(1) сможет перечислить машины, через которые идут пакеты до целевой машины.
Имейте ввиду: не все маршрутизаторы уменьшают TTL. Некоторые из них могут оказаться прозрачными для traceroute(1).
Для примера, попробуем выяснить маршрут к несуществующей сети:
$ traceroute -n 10.0.0.1 traceroute to 10.0.0.1 (10.0.0.1), 64 hops max, 40 byte packets 1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms 2 172.16.0.1 1.703 ms !H 0.585 ms !H 0.491 ms !H
Здесь мы выполняли команду traceroute(1) на машине 172.16.0.2. Она не знает маршрута к хосту 10.0.0.1 и пересылает пакет на машину 172.16.0.1 — свой маршрутизатор по умолчанию, а тот вернул ответ «Destination Host Unreachable», о чём свидетельствует флаг !H. Эта строка появилась потому, что брандмауэр на маршрутизаторе 172.16.0.1 не выпускает пакеты предназначенные для приватных сетей на свой дефолтный маршрутизатор возвращая ICMP пакет с сообщением об ошибке. Строка с номером 1 это результат работы первого пакета ICMP, в котором TTL был выставлен в 1. Этот пакет достиг машины 172.16.0.1, но дальнейшей маршрутизации не претерпел, так как у него истёк срок жизни, поэтому сообщение об ошибке сгенерировано не было. И только следующий пакет ICMP с TTL=2, породил сообщение об ошибке.
Далее идут несколько умозрительные примеры, почёрпнутые из справки по команде traceroute(1).
$ traceroute -n 192.168.2.1 traceroute to 192.168.5.1 (192.168.5.1), 64 hops max, 40 byte packet 1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms 2 192.168.0.1 39 ms 39 ms 19 ms 3 192.168.0.1 39 ms 39 ms 19 ms 4 192.168.1.1 39 ms 40 ms 39 ms 5 192.168.2.1 39 ms 39 ms 39 ms
Заметьте, что строки 2 и 3 совпадают — это происходит потому, что на втором маршрутизаторе имеются ошибки в ядре — система 4.3BSD маршрутизирует пакет с нулевым TTL.
$ traceroute -n 192.168.9.1 traceroute to 192.168.9.1 (192.168.9.1), 64 hops max 1 172.16.0.1 0.418 ms 0.781 ms 0.228 ms 2 192.168.0.1 39 ms 39 ms 19 ms 3 192.168.0.1 39 ms 39 ms 19 ms 4 192.168.1.1 39 ms 40 ms 39 ms 5 192.168.2.1 39 ms 39 ms 39 ms 6 * * * 7 192.168.4.1 259 ms 499 ms 279 ms 8 * * * 9 * * * 10 * * * 11 * * * 12 192.168.9.1 339 ms 279 ms 279 ms
Шлюзы 6, 8, 9, 10 и 11 либо не высылают нам ICMP с сообщением «time exceeded», либо у их сообщений слишком маленький TTL и оно нас не достигает. В точности нельзя сказать, что происходит на маршрутизаторе 12. Например, это может быть следствием ошибок в ядре 4.[23]BSD: BSD 4.x (x меньше либо равен 3) высылали сообщение об ошибке используя TTL оригинального пакета. Таким образом, ICMP «time exceeded» принципиально не мог до нас добраться.
У программы traceroute(1) есть ещё один полезный аргумент: -P [TCP|UDP|ICMP|...], с помощью которого можно задать используемый протокол. По умолчанию в системах BSD (и в Linux тоже) traceroute(1) высылает пакеты UDP направленные на абстрактный верхний порт. Такие пакеты могут резать брандмауэры, поэтому и предусмотрена возможность выбора протокола. Опция -I включает протокол ICMP. С её помощью traceroute(1) работает так же, как утилита tracert в Windows.