Описание протокола
ICMP (Internet Control Message Protocol) — протокол межсетевых управляющих соединений. Используется в основном для передачи сообщений об ошибках. Например, может информировать узел-отправитель, что сеть или узел-получатель недостижимы или необходима фрагментация, если установлен флаг DF (Don’t fragment) и так далее.
Сам протокол находится на сетевом уровне, однако также частично выполняет функции транспортного уровня. Все ICMP пакеты инкапсулируются в IP пакеты:
А вот и расположение протокола в модели OSI:
Какие функции транспортного уровня он выполняет?
Сообщает об ошибках, возникающие в сети, потому что протокол IP не предоставляет никакие механизмы по оповещению узлов в случае возникновения сетевых проблем. Поэтому данные функции и возложены на ICMP.
Но разве это не делает TCP и протоколы прикладного уровня?
TCP и протоколы прикладного уровня применяют данные механизмы в случаях, когда соединение уже установлено или на стадии установления. К тому же, если на сетевом уровне имеется проблема, то пакет никогда не дойдет до транспортного и прикладного уровней и соответственно “верхние” протоколы ничего не смогут сделать и даже ничего не будут знать.
Поясню на простом примере. Мы уже знаем как работает фрагментация пакетов. Теперь представим, что мы отправляем данные и устанавливаем флаг DF (Don’t fragment). На пути следования пакетов одному из узлов вдруг потребуется провести фрагментацию, но так как у нас установлен флаг DF, то узел не сможет обработать запрос и естественно не отправит пакет на транспортный уровень для дальнейшей обработки. Пакет будет уничтожен и если бы не ICMP, то узел-отправитель и дальше бы отправлял пакеты с запретом на фрагментацию, а пользователи бы не знали в чем проблема.
Поэтому, уничтожив пакет, узел-получатель формирует специальный ICMP ответ с указанием, что требуется фрагментация.
А вот и другой пример. Все мы любим интернет и введя в адресной строке название сайта просматриваем содержание сайта. Чтобы не вдаваться во все подробности процесса рассмотрим общую схему данного процесса.
Наш компьютер формирует пакеты и отправляет их модему (маршрутизатору), а тот в свою очередь отправляет их интернет-провайдеру. Процесс перенаправления пакетов от одного узла к другому работает на сетевом уровне. Теперь представим, что этот самый модем не знает куда отправить наши пакеты (причин может быть несколько). А если не знает, что с ними делать, то просто их уничтожит.
И здесь снова на помощь приходит ICMP. Уничтожив пакет, модем сформирует сообщение, что сеть недостижима и отправит на наш компьютер. А компьютер в свою очередь отобразит в браузере, что нет подключения к интернету.
Из всего этого видно, что даже на сетевом уровне необходим механизм по контролю за ошибками.
А что произойдет, если сгенерированный ICMP пакет был потерян?
Ничего, повторно пакет высылаться не будет.
А как же выглядит сам заголовок ICMP пакета?
Заголовок состоит из 8 байт и выглядит следующим образом:
Тип — числовой идентификатор типа сообщения. Например, когда адресат недостижим, то устанавливается значение 3.
Код — числовой идентификатор ошибки, то есть более подробно описывает тип сообщения. Например, если требуется фрагментация, то Тип сообщения равен 3, а Код ошибки — 4.
Контрольная сумма — стандартная проверка пакета ICMP на наличие ошибок.
Данные — в зависимости от значений в полях Тип и Код передаются определенные данные.
Вот как выглядят некоторые сообщения в сниффере Wireshark:
Ping
С помощью ICMP можно также проверить доступность определенных узлов в сети или провести простое сетевое сканирование.
Достигается это с помощью простой техники. Узел-отправитель генерирует пакет Echo request (эхо запрос) и отправляет его определенному узлу-получателю. Узел-получатель, приняв пакет, ответит узлу-отправителю пакетом Echo reply (эхо ответ). Когда узел-отправитель получит ответ, то измерит задержку распространения пакетов в сети и возможные потери и отобразит результаты на экране. Реализуется это с помощью утилиты Ping, которая доступна на многих платформах (Windows, Linux).
Если пакеты не достигнут узла-получателя, то на экране узла-отправителя отобразится такой результата:
То есть это означает, что узел выключен или не подключен к сети?
Не совсем. Причин неуспешного пинга может быть несколько. Например, не работает маршрутизация, ICMP пакеты блокируются и так далее. То есть Ping не дает стопроцентной гарантии того, что узел выключен.
На основе техники Echo request — Echo reply и строятся многие инструменты сетевой диагностики.
Tracert/Traceroute
Другой полезный инструмент, работающи й на основе ICMP способен строить карту сети, то есть отмечает все промежуточные узлы, через которые прошел пакет. Таким способом можно проверить как работает сеть и каким путем следуют пакеты к узлу-получателю. Кроме того, при возникновении сетевых проблем данная утилита поможет найти узел, который возможно является причиной сетевой проблемы. Достигается это с помощью утилиты Traceroute (Linux) либо Tracert (Windows).
Вот как выглядит работы программы:
А как работает данная программа?
Работа основана на том, что каждый узел (маршрутизатор), который перенаправляет пакеты в другую сеть уменьшает TTL пакета на 1. Когда TTL равна 0, то узел уничтожит пакет и сгенерирует ICMP сообщение Time Exceeded (Время жизни пакета истекло) и отправит узлу-отправителю.
Поэтому при запуске Traceroute генерирует первый пакет Ping Echo Request с TTL = 1. Первый маршрутизатор на пути следования пакета уменьшит TTL и отправит сообщение Time Exceeded. Причем данный пакет будет содержать IP адрес данного маршрутизатора в качестве узла-отправителя (Source IP address), а в качестве узла-получателя будет выступать узел, который запустил программу Traceroute.
Затем Traceroute сгенерирует второй пакет, но уже с TTL = 2. Первый маршрутизатор уменьшит TTL на 1 и отправит на следующий маршрутизатор, который тоже уменьшит TTL и если он станет равным 0, то уничтожит его и отправит Time Exceeded с указанием своего адреса. И так продолжается до тех пор, пока пакет не достигнет узла-получателя либо пока не закончится цикл отправки пакетов, который по умолчанию равен 30. Таким образом программа Traceroute и узнает обо всех маршрутизаторах в маршруте следования пакетов.
Вот как выглядит трафик в анализаторе Wireshark:
Иногда можно увидеть и такой трейс:
Что означают звездочки в выводе программы и сообщения Request timed out?
Это означает, что наш компьютер не получил никаких пакетов Time Exceeded, потому что маршрутизатору запрещено отправлять пакеты Time Exceeded. Сделано это в целях безопасности.