ICMP протокол диагностики перегрузки сети [АйТи бубен]

Основы протокола icmp

Протокол ICMP (Internet Control Message Protocol) используется для диагностики сетевых
подключений, а также для передачи удаленным системам сообщений об исключительных ситуациях, возникающих в процессе
работы стека TCP/IP. ICMP работает на сетевом уровне модели сетевого взаимодействия;

при этом ICMP инкапсулирует
свои сообщения в IP-пакеты; реализация ICMP является обязательной для стека TCP/IP. ICMP-сообщение состоит из
заголовка (содержит идентификаторы типа и кода сообщения, а также контрольную сумму) и поля данных, содержимое
которого зависит от назначения сообщения
[
7
] .

Основные понятия и термины

Каждое DCCP соединение реализуется между двумя партнерами, которые будут называться DCCP A и DCCP B. Данные могут передаваться в обоих направлениях. В рамках протокола рассматриваются субнаборы соединений, называемых полусоединениями (halfconnection – HC).

(Смотри рис. 3.12.) Эти полусоединения обеспечивают передачу информационных пакетов в одном направлении плюс соответствующих подтверждений в противоположном направлении. В контексте одного полусоединения HC-отправитель является партнером отправителем данных, в то время как HC-Receiver является партнером, посылающим подтверждения.

Каждое полусоединение контролируется механизмом управления перегрузкой, специфицированным однобайтовым идентификатором, или CCID. Партнеры согласуют режим обмена на фазе формирования соединения. CCID для полусоединения описывает, как HCотправитель ограничивает поток информационных пакетов; как он поддерживает необходимые значения параметров, такие, как окна перегрузки; как HC-получатель уведомляет отправителя о перегрузке, посылая подтверждения; и как он поддерживает частоту подтверждений.

Основные отличия dccp от tcp

Ниже рассмотрены наиболее существенные отличия DCCP от TCP.

  • Поток пакетов. DCCP является протоколом для потоков пакетов, а не потоков байт.
  • Ненадежность. DCCP никогда не пересылает дейтаграммы повторно.
  • Порядковые номера пакетов. Порядковые номера относятся к пакетам, а не к байтам. Каждому пакету, посылаемому DCCP, присваивается новый порядковый номер, то же и с пакетами подтверждений. Это позволяет получателю пакетов DCCP детектировать потери подтверждений; смотри раздел “Sequence Number Validity” в [DCCP].
  • Обширное пространство для опций (до 1020 байт).
  • Согласование параметров. Это является базовым механизмом, с помощью которого партнеры согласуют значения параметров или свойства соединения.
  • Выбор управления перегрузкой. Партнеры могут использовать разные механизмы управления перегрузкой. В соединении A<>B информационные пакеты, посланные от A>B, могут применять алгоритм CCID 2, а пакеты данных от B>A могут использовать CCID 3.
  • Различные форматы подтверждений. CCID соединения определяет, какой объем данных должно быть передан в ack. В CCID 2 (TCP-подобном) посылается один ack на 2 пакета, а каждый ack должен оповещать, какие конкретно пакеты получены (опция Ack Vector); в CCID 3 (TFRC) посылается в среднем один ack за время RTT, а ack должны сообщать как минимум о длинах последних интервалов потерь.
  • Отсутствие приемного окна. DCCP является протоколом управления перегрузкой, а не протоколом управления потоками.
  • Разделение различных видов потерь. Опция потерянных данных (Data Dropped) позволяет одному из партнеров сообщить, что пакет был потерян изза повреждения, переполнения входного буфера и т.д..
  • Определение подтверждения. В TCP получение пакетов подтверждается, только когда они ставятся в очередь для передачи приложению. В протоколе DCCP это делается не так. Получение пакета подтверждается, когда обработаны поля его опций.
  • Встроенная поддержка мобильности.

Введение

Протокол DCCP (Datagram Congestion Control Protocol) является транспортным протоколом, который использует двунаправленные уникастные соединения с управлением перегрузкой для ненадежной доставки дейтаграмм.

Протокол DCCP предназначен для приложений, которые реализуют поточную схему TCP, но имеют приоритет для своевременной доставки данных с сохранением порядка кадров или требуют надежности, или для приложений, которые требуют механизма подавления перегрузки, отличного от TCP.

До настоящего времени такие приложения использовали либо TCP, чья надежность и гарантия упорядочения доставки давалась за счет неопределенно большой задержки, либо UDP и независимый механизм управления перегрузкой (или вообще с отсутствием подавления перегрузки).

Протокол DCCP предназначен для приложений, которые не требуют параметров SCTP [RFC-2960], таких, как упорядоченная доставка при нескольких потоках.

Протокол UDP исключает большие задержки, но приложения UDP, которые используют управление перегрузкой, вынуждены вносить задержки сами. Протокол DCCP имеет встроенную систему управления перегрузкой, включая поддержку ECN для ненадежных потоков дейтаграмм и исключая непредсказуемые задержки, характерные для TCP. Протокол DCCP обеспечивает надежное согласование параметров при установлении соединения.

Одной из целей DCCP было максимальное облегчение для UDP приложений перехода на DCCP, когда он будет внедрен. Чтобы облегчить это, DCCP был спроектирован с минимальной избыточностью как с точки зрения размера заголовка пакета, так и с позиции загрузки ЦПУ машин партнеров.

В DCCP была включена минимальная функциональность, при сохранении возможности включения новых функций, таких, как FEC (forward error correction), псевдонадежность и множественные потоки, которые могут быть добавлены поверх DCCP, если потребуется.

Возможны разные механизмы управления перегрузкой для разных приложений. Например, игры реального времени могут требовать быстрого использования всей доступной полосы пропускания, в то время как потоковая среда может использовать компромисс между скоростью отклика и стабильной, менее импульсивной передачей.

(Резкое изменение потока может вызвать неприемлемые сбои UI, такие, как слышимые паузы или щелчки). Протокол DCCP, таким образом, предлагает приложению выбор одного из нескольких механизмов управления перегрузкой. Одной из альтернатив является TCP-подобное управление перегрузкой, сокращение вдвое окна перегрузки в ответ на потерю пакета.

Приложения, применяющие механизм управления перегрузкой, будут быстро реагировать на изменения доступной полосы, но должны выдерживать резкое изменение окна перегрузки, что типично для TCP. Вторую альтернативу представляет механизм управления скоростью передачи, дружественный по отношению TCP (TFRC)

Протокол DCCP позволяет также ненадежному трафику без проблем использовать технику ECN. Ядро UDP API не может позволить приложениям считать UDP пакеты адаптированными к ECN, так как API не может гарантировать, что приложение способно корректно детектировать или реагировать на перегрузку.

В DCCP было решено не применять менеджер управления перегрузкой [RFC-3124], который допускает несколько одновременных потоков между отправителем и получателем. Менеджер перегрузки может быть использован только приложениями, которые имеют свою собственную обратную связь в случае потери пакетов между конечными точками соединения, но этого нет во многих приложениях, работающих с UDP.

Кроме того, сегодняшний вариант менеджера перегрузки, как правило, не поддерживает более одного механизма управления перегрузкой. DCCP должен быть способен использовать механизм управления перегрузкой там, где это требуется приложению.

Предполагается, что протокольные механизмы DCCP, будут адаптированы к любому приложению, требующему уникастных потоков с управлением перегрузки. Механизмы управления перегрузкой, встраиваемые в DCCP, описаны в отдельных ID профайлах управления [CCID 2 PROFILE, CCID 3 PROFILE], они могут, однако вызвать проблемы для некоторых приложений, включая широкополосное интерактивное видео.

Протокол DCCP имеет следующие характеристики:

  • реализует поток дейтаграмм с подтверждением получения, но без повторной посылки;
  • ненадежный диалог установления и разрыва соединения;
  • надежное согласование параметров;
  • выбор механизмов подавления перегрузки, дружественных по отношению к TCP, включая TCP-подобное управление перегрузкой (CCID 2) и управление потоком [RFC-3448] (CCID 3). CCID 2 использует разновидность TCP-механизма управления перегрузкой и приемлемо для потоков, которые стремятся воспользоваться преимуществами доступной полосы, CCID 3 пригодно для потоков, которые требуют более стабильной скорости передачи;
  • опции, которые говорят отправителю с высокой надежностью, какие пакеты достигли получателя, были ли эти пакеты помечены ECN [RFC-3168 и RFC-3540], повреждены или отброшены во входном буфере получателя;
  • управление перегрузкой, снабженное встроенной индикацией явной перегрузки ECN (Explicit Congestion Notification);
  • механизмы, позволяющие серверу избежать поддержки состояний неподтвержденных попыток соединений;
  • выявление MTU пути [RFC-1191].
:/>  Веб-камеры как выбрать и не работает веб-камера в Windows 10, как это исправить?

Icmp протокол диагностики перегрузки сети [айти бубен]

ICMP (Internet Control Message Protocol — межсетевой протокол управляющих сообщений). ICMP является протоколом контрольных сообщений Структура межсетевого протокола IPv4. Протокол ICMP используется устройствами сети для отправки управляющих сообщений и сообщений об ошибках на компьютеры и серверы. Существует несколько областей применения протокола ICMP, например, объявление об ошибках в сети, объявление о перегрузке сети и устранение неполадок.

Каждое сообщение протокола ICMP передается по сети внутри пакета IP. Пакеты IP с сообщениями ICMP маршрутизируются точно так же, как и любые другие пакеты, без приоритетов, поэтому они также могут теряться. Мало того, при большой загруженности сети они могут вызывать дополнительную загрузку маршрутизаторов. Для того, чтобы не вызывать лавины сообщения об ошибках, предусмотрели, что в случае потери пакетов IP, которые сами “несут” сообщения ICMP об ошибках, новые сообщения ICMP об ошибке рождаться не будут.

ICMP только сообщает о возникших ошибках отправителю пакета; отправитель сам должен связать ошибки с конкретными прикладными программами и предпринять действия по исправлению ошибок.

Надо отметить, что большая часть ошибок исходит от отправителя, но другие – нет. Так как ICMP сообщает об ошибках отправителю, он не может использоваться, чтобы информировать промежуточные маршрутизаторы об ошибках. Например, пакет следует по пути через маршрутизаторы М1,М2,…,Мk. Если Мk содержит некорректную информацию о маршрутах и ошибочно отправит пакет на маршрутизатор Ме, то маршрутизатор Мe может лишь сообщить об ошибке отправителю пакета. К сожалению, отправитель не отвечает за эту проблему и не может управлять некорректно ведущим себя маршрутизатором Мk. Фактически, отправитель не сможет даже определить, какой маршрутизатор вызвал эту проблему.

Почему ограничивают протокол ICMP взаимодействием только с отправителем? Потому что IP- пакет содержит поля, которые определяют только отправителя и получателя; он не содержит полного описания своего пути через сеть (кроме необычных случаев, о которых мы скажем позже).

Если маршрутизатор обнаруживает ошибку, он просто не может узнать, какие промежуточные машины обрабатывали этот пакет, и поэтому не может сообщить им об ошибке. Вместо простого удаления пакета этот маршрутизатор использует протокол ICMP, чтобы сообщить отправителю о возникшей проблеме, надеясь на то, что администратор сети затем локализует и исправит ошибку.

ICMP протокол диагностики перегрузки сети [АйТи бубен]

Расшифровка кодов ICMP сообщений:

Ответ на некоторые ICMP-сообщения может привести к разглашению некоторой информации о хосте, в то время как другие — привести к модификации таблицы маршрутизации, поэтому их необходимо запретить.

Обычно выход во внешний мир разрешают ICMP-сообщениям 3, 8, 12, в то время как на вход принимают только 0, 3, 4, 11, 12.

Инициация и разрыв соединения

Любое соединение DCCP предполагает формирование DCCP сокетов в пассивном состоянии прослушивания. Активной стороной считается клиент, а роль пассивной стороны выполняет сервер.

Пакеты dccp

Протокол DCCP использует девять различных типов пакетов: DCCP-Request, DCCP-Response, DCCP-Data, DCCP-Ack, DCCP-DataAck, DCCP-CloseReq, DCCP-Close, DCCP-Reset, и DCCP-Move.

DCCP-Request

Посылается клиентом для инициализации соединения (первый шаг трехходовой процедуры).

DCCP-Response

Посылается сервером в ответ на запрос DCCPRequest (второй этап трехшаговой процедуры инициации соединения).

DCCP-Data

Используется для передачи прикладных данных.

DCCP-Ack

Используется для передачи только подтверждений.

DCCP-DataAck

Используется для передачи прикладных данных в сочетании с подтверждениями.

DCCP-CloseReq

Посылается сервером для предложения клиенту закрыть соединение.

DCCP-Close

Используется клиентом или сервером для закрытия соединения; также для запуска процедуры сброса (DCCPReset).

DCCP-Reset

Используется для закрытия соединения, обычным или необычным образом.

DCCP-Sync, DCCP-SyncAck

Используется для ресинхронизации номеров пакетов после длительного периода потерь.

Процедура взаимодействия партнеров включает в себя следующие обмены.

  1. Клиент посылает серверу пакет DCCP-Request, специфицируя номера портов клиента и сервера, запрашиваемый сервис, и любые параметры, подлежащие согласованию, включая CCID, который должен использовать сервер при работе с клиентом. Клиент может опционно подключать к пакету DCCP-Request некоторые данные.
  2. Сервер посылает клиенту пакет-отклик, уведомляя его о своем желании осуществить обмен данными. В отклике указываются любые особенности и опции, которые предлагает сервер. Опционно отклик может содержать Init Cookie.
  3. Клиент посылает серверу пакет DCCP-Ack, который подтверждает получение пакета DCCP-отклика.
  4. Далее следуют обмен нулем или более подтверждениями DCCP-Ack, если требуется завершить согласование используемых параметров.
  5. Сервер и клиент обмениваются пакетами DCCP-Data, DCCP-Ack. Если у клиента нет данных, тогда сервер посылает пакеты DCCP-Data и DCCP-DataAck, в то время как клиент будет посылать только DCCP-Acks.
  6. Сервер посылает пакет DCCP-CloseReq, запрашивая закрытие соединения.
  7. Клиент посылает пакет DCCP-Close, подтверждая закрытие.
  8. Сервер посылает пакет DCCP-Reset, в котором поле причина содержит “Closed”, при этом состояние соединения ликвидируется.
  9. Клиент получает пакет DCCP-Reset и сохраняет свое состояние в течение некоторого времени для завершения происходящих обменов.

Статья – asm для х86. (5.3) протокол icmp – ping и traceroute

Продолжим круиз по стеку протоколов TCP/IP, и на этот раз остановимся на ICMP.

В реализации этого протокола нет ничего сложного – он примитивен как амёба. Однако в умелых руках ICMP превращается в грозное оружие, из-за чего Microsoft поспешила на корню отрубить к нему доступ, оставив прогерам на растерзание лишь пару функций из библиотеки iphlpapi.dll – вот их список:

  1. IcmpCreateFile() – создать ICMP сессию;
  2. IcmpSendEcho() – отправить эхо-запрос получателю;
  3. IcmpCloseHandle() – закрыть текущую сессию.

Мдаа.. не густо.. От большого куска ICMP-протокола нам остался лишь унылый PING. В никсах дела обстоят намного лучше. Обычные их сокеты-Беркли позволяют оперировать с сокетами типа IPPROTO_ICMP, хотя под виндой этот тип уже не поддерживается, и функция socket() с аргументом ICMP тут-же возвращает ошибку. Но что так напугало мелкомягких и почему они решились на такой отчаянный шаг? Давайте разбираться..

5.3.0. Назначение протокола ICMP

Под аббревиатурой ICMP кроется

“Internet Control Message Protocol”

. Протокол был введён для обмена сообщениями об ошибках между маршрутизаторами. Например отправили мы из своей сети пакет адресату, а адресат находится в другой сети и в данный момент по каким-то причинам не доступен

(узел выключен, или кабель перебит).

В этом случае, можно долго томиться в ожидании ответа, и по истечении тайм-аута так и не узнать об истинной причине отказа. Здесь и приходит на помощь ICMP, который оправляет нам смс’ку с кодом ошибки.

Примечательным является тот факт, что ICMP является частью протокола IP и делит с ним ложе на сетевом уровне(2) стека TCP/IP. Такой расклад приводит к тому, что хоть маршрутизатор и отправит нам сообщение об ошибке, нет никакой гарантии что мы его получим. Из протоколов сетевого стека, гарантировать доставку может только протокол транспортного уровня TCP, а он находится по лестнице выше IP. Задачей протокола ICMP является передача информации о проблемах в коммуникационной среде, но отнюдь не повышение уровня надёжности IP.

:/>  Надписи для Steam - Rep, Report, Like, Doge, Icon CS:GO и другие

В глобальных сетях маршрутизатор

(он-же шлюз и роутер)

представляет собой специально выделенный для перенаправления трафика компьютер. Он имеет карту IP-адресов своих клиентов, в числе которых и следующие в цепочки шлюзы. Всё-что делает маршрутизатор, это сверяет поле с адресом получателя в IP-заголовке пакета со своей таблицей маршрутизации, и если такого IP-адреса не обнаруживает, то перенаправляет трафик соседнему маршрутизатору. На рисунке представлена схема подключения нескольких локальных сетей, при помощи маршрутизаторов R1-RN (route):

Здесь видно, что если узел из сети(B) захочет переслать пакет например узлу в сети(С), то пакет ждёт экстремальное путешествие – это коммутатор и сервак в своём периметре… после чего пакет выходит наружу и прямиком попадёт в лапы маршрутизатора R2. В маршрутной карте R2 прописаны IP-адреса только узлов сети(В) и оккупировавших его с двух сторон соседних маршрутизаторов R1 и R3.

Теперь R2 уменьшает в IP-заголовке пакета значение TTL на единицу, и перенаправляет пакет по цепочке дальше, в объятия маршрутизатора R3. Тот видит, что указанный IP-адрес имеется в его таблице, и пропускает пакет в свою сеть. В контексте данной темы,

декремент значения TTL для нас в приоритете

– именно на этот факт опирается утилита

TRACERT

, которая работает как-раз по протоколу ICMP.

Нужно иметь в виду, что маршрутизаторы общаются между собой по своим правилам. Если сеть небольшая, таблица маршрутизации может заполняться админом вручную. Однако в больших сетях таблицы заполняются уже динамически, самим маршрутизатором при помощи ARP-запросов. Например он может на автомате определять добавление новой сети, недоступность пункта назначения по тайм-ауту, добавление в сеть нового маршрутизатора, который может обеспечить более короткий путь к месту назначения и т.д.

Протоколом маршрутизации внутри автономных систем являлся протокол внутреннего шлюза “Interior Gateway Protocol” или

IGP

. Его расширением стал “Routing Information Protocol”

RIP(не путать с посмертной надписью)

. Однако новый протокол “Open Shortest Path First”

OSPF

имеет более продвинутый набор возможностей, и в дословном переводе означает

“Сначала открывать самый короткий путь”

– в этом случае маршрутизатор отправляет ICMP сообщение типа(5) – Redirect. На радость устаревшим IGP и RIP, большинство маршрутизаторов поддерживают все перечисленные протоколы, хотя пальмовую ветвь носит OSPF.

5.3.1. Обзор протокола ICMP и типы его ошибок

Сообщения ICMP обычно содержат информацию об ошибках при обработке пакетов маршрутизаторами. Вполне возможна ситуация, когда сообщения будут передаваться в непрерывном режиме, полностью забивая пропускную способность канала. Чтобы предотвратить такой беспредел, маршрутизаторы не должны передавать сообщения ICMP, которые связаны с ошибками самих-же сообщений ICMP. При возникновении ошибок в процессе обработки нескольких кадров одного (фрагментированного) пакета, сообщения должны передаваться только для первого фрагмента. В прошлой части говорилось, что первым считается тот, у которого значение “Offset” в заголовке равно нулю.

В качестве несущего, ICMP использует ненадёжный и без установки связи протокол IP. Существуют две категории сообщений –

сообщения об ошибках

, и

управляющие запросы

. Первые сообщают о проблемах, с которыми может столкнуться маршрутизатор при обработке пакета. В свою очередь управляющие сообщения всегда ходят парами “запрос-ответ”, и помогают админу выудить конкретную информацию у маршрутизатора – это касается таких инструментов как PING и TRACEROUTE.

Сообщения ICMP инкапсулируются в пакеты IP и имеют свой формат. Именно по этой причине мастдай наглухо забил гвоздями дверь на этот уровнь, т.к. при благоприятных условиях мы сами должны были формировать заголовки IP и ICMP, а значит без труда могли подменить IP-адрес отправителя. Такой/левый пакет по конвейеру поступил-бы на физический уровень стека TCP/IP, где драйвер TDI дополнил-бы пакет только MAC-адресом и выпустил-бы его в белый свет. В следующей части мы вернёмся к этому вопросу и рассмотрим его подробней.

Детали протокола ICMP описывает

спецификация RFC-792.

Если коротко, то нужно создать структуру

ICMP_Header

и разместив её после IP-заголовка, отправить получателю посредством WinSock функции

sendto()

. В таблицах ниже представлена структура ICMP-сообщения и возможные варианты поля Type:

Обычно прикладные программы только получают сообщения об ошибках – отправкой занимаются системные демоны. В числе запросов которые мы могли-бы отправить можно выделить лишь сообщение с типом(8) – это знакомый большинству из нас

эхо-запрос PING.

Но и в этом случае, как упоминалось выше, мастдай

(редиска)

забрал у нас эти права, а взамен вручил уже готовую функцию

IcmpSendEcho()

. Так-что нам остаётся лишь фильтровать входящий трафик на сообщения с ошибками. Выход – или ставить W2K

(тогда о переносимости приложения можно забыть)

, или менять коня на Linux

(что для привыкших к Win смерти подобно).
5.3.2. Практика – пишем утилиту PING

Здесь может возникнуть логичный вопрос – зачем тратить время и силы на свой пинг, когда в системе есть уже готовая утилита? Есть-то она есть, только каждый раз звать её из своего приложения слишком накладно. Можно даже вставить в код профайлер, и засечь время выполнения внешней утилиты – результат явно не обрадует. Если мы захотим из своего кода пропинговать не один, а например сразу сотни узлов

(создав для каждого свой поток)

, то проще добежать до них пешком, чем воспользоваться системной тулзой PING. Поэтому практичней вызывать оптом и врозницу всего одну функцию

IcmpSendEcho()

с таким прототипом.. В случае ошибки, в регистре EAX она возвращает (-1), иначе – кол-во ответов хоста

(как правило один)

:

Данные мы можем не отправлять, зато необходимо предварительно заполнить структуру

“IP_OPTIONS_INFO”

, внутри которой имеются два интересных поля – это

TTL

и флаги. Под виндой, флагов всего два и они дают постановку МАС-уровню – фрагментировать пакет, если данные в нём превышают лимит

(MF = more

), или-же не фрагментировать его ни при каких обстоятельствах

(DF = don’t fragment).

Значение в поле TTL определяет макс кол-во маршрутизаторов, которые сможет преодолеть наш PING:

После того как

IcmpSendEcho()

отправит запрос, удалённый хост заполнит наш приёмный буфер специальным пакетом. Этот пакет описывает структура WinSock под названием

ICMP_ECHO_REPLY

– вот её формат:

Таким образом, от нас требуется лишь задать опции, и для пущей вероятности в цикле отправить несколько раз один и тот-же запрос. Причём в каждой итерации цикла получим свою порцию инфы, которую пропарсив выведем на экран. Возможный вариант кода самопального PING представлен ниже:

C-подобный:

format pe console
entry start
include 'win32ax.inc'
;----------
.data
wsa WSADATA
ipOpt IP_OPTIONS_INFO
capt db 13,10,' PING example v0.1' db 13,10,' ******************************' db 13,10,' Type host.......: ',0
ping db 13,10 db 13,10,' Host.........: %s' db 13,10,' Time.........: %.2ld ms' db 13,10,' TTL..........: %d' db 13,10,' Packet size..: %d bytes',0
succes db 13,10 db 13,10,' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' db 13,10,' PING successful..' db 13,10,' Press any key for exit...',0
frmt db '%s',0 ; спецификатор для scanf()
hndl dd 0 ; под дескриптор ICMP сессии
addr dd 0 ; под IP-адрес назначения
count dd 2 ; счётчик запросов PING
outPack db 'Marylin example Ping' ; необязательные данные,
outPackLen dd $ - outPack ; ..и их размер.
inPack db 128 dup(0) ; приёмный буфер
errMes db 128 dup(0) ; буфер для строки с ошибкой
hostName db 64 dup(0) ; сюда юзер введёт имя хоста для пинга
;---------
.code
start:
;//--- Выводим шапку и принимаем имя хоста у юзера ------- invoke WSAStartup,0x0101,wsa ; cinvoke printf,capt ; cinvoke scanf,frmt,hostName ;
;//--- Обрабатываем введённую строку и получаем IP назначения ----------- invoke inet_addr,hostName ;// это IP вида "127.0.0.1" ??? cmp eax,-1 ; 0xFFFFFFFF = ошибка jnz @create ; если нет ошибки.. invoke gethostbyname,hostName ;// это имя типа "mail.ru" ??? or eax,eax ; 0 = ошибка jnz @name ; если No_Zero.. stdcall GetError ; иначе: встречаем её! jmp @exit ; ..и на выход.
@name: ; юзер ввёл имя (не IP)
virtual at eax ; в EAX лежит адрес структуры "hostent"
host hostent ; определяем её как виртуальную
end virtual ; mov eax,[host.h_addr_list] ; берём из "hostent" 4-байтный IP mov eax,[eax] ; ^^^ mov eax,[eax] ; ^^^
@create: mov [addr],eax ; запомнить его в переменной!
;//--- Создаём ICMP сессию и задаём опции ------- invoke IcmpCreateFile ; создать сессию! mov [hndl],eax ; запомнить её дескриптор mov [ipOpt.Ttl],32 ; выставляем для пинга TTL=32 mov [ipOpt.Flags],IP_FLAG_DF ; флаг = не фрагментировать
;//--- Непосредственно PING в цикле -------------
@send: mov eax,[addr] ; EAX = IP назначения invoke IcmpSendEcho,[hndl],eax, ; отправить эхо-запрос!!! outPack,[outPackLen], ; ^^^ ipOpt,inPack,128,3000 ; ^^^ тайм-аут = 3000 ms
;//--- Парсим приёмный буфер ICMP_ECHO_REPLY ---- xor ebx,ebx ; EBX, EDX = 0 xor edx,edx ; mov esi,inPack ; ESI = адрес буфера с ответом mov eax,[esi] ; EAX = IP отправителя invoke inet_ntoa,eax ; перевести его в строку mov bl,[ipOpt.Ttl] ; EBX = TTL mov ecx,dword[esi 8] ; ECX = "RoundTripTime" потраченое время mov dx,word[esi 12] ; EDX = размер данных в байтах cinvoke printf,ping,eax,ecx,ebx,edx ; вывод бодяги на экран! dec [count] ; счётчик -1 jnz @send ; повторить, если счётчик не нуль
;//--- Финальная стадия ------------------------ cinvoke printf,succes ; мессага "Всё ОК!"
@exit: invoke IcmpCloseHandle,[hndl] ; прибить ECHO-сессию cinvoke scanf,frmt,frmt 5 ; ждём нажатия клавиши.. invoke ExitProcess,0 ; на выход!
;//---------------------------------------------
;//--- Вспомогательная функция обработки ошибок
;//--- выводит характер ошибки в текстовом виде.
;//---------------------------------------------
GetError: invoke WSAGetLastError invoke FormatMessage,0x1000,0,eax,0,errMes,128,0 invoke CharToOem,errMes,errMes cinvoke printf,errMes
ret
;//--- Секция импорта ------
section '.idata' import data readable ;
library kernel32,'kernel32.dll', ; импортируемые библиотеки user32,'user32.dll', ; ^^^ wsock32,'wsock32.dll', ; ^^^ msvcrt,'msvcrt.dll', ; ^^^ iphlp,'iphlpapi.dll' ; ^^^
import iphlp, IcmpSendEcho,'IcmpSendEcho',IcmpCreateFile,'IcmpCreateFile', IcmpCloseHandle,'IcmpCloseHandle'
import msvcrt, printf,'printf',scanf,'scanf'
include 'apikernel32.inc'
include 'apiuser32.inc'
include 'apiwsock32.inc'

Скрин снифера

:/>  Как настроить тихий микрофон в Windows XP/7/10 💻

” Wireshark”

показывает, что ICMP-пакеты не выходят из уровня IP.

Хоть я и отправлял запросы из своего пользовательского приложения, транспортные уровни TCP и UDP стека протоколов остались не при делах, и даже не подозревают об отправки мной запроса. Другими словами, в протоколе ICMP вообще отсутствует понятие порт, и весь обмен происходит исключительно на уровне маршрутизаторов IP.

5.3.3. Утилита TRACEROUTE

..это из той-же кухни, что и PING.

Основное назначение – хитростью отследить маршрут пакета от источника, к месту назначения. Мы уже знаем, что каждый маршрутизатор в сети уменьшает на единицу значение TTL в IP-заголовке пакета. Если маршрутизатор обнаруживает пакет с TTL=0, он дропает его и отправляет нам ICMP-сообщение

типа(11)

, что означает “Лимит времени истёк”

(см.таблицу с кодами ошибок выше)

. Так-как сообщение отправляет именно маршрутизатор, значит он-же и вставит в сообщение свой IP-адрес. Айпишник в полученной мессаге сдаёт маршрутизатор с потрахами и нам остаётся лишь вывести его на экран.

TRACEROUT – чемпион по бегу в мешках. Он прыгает от маршрутизатора к маршрутизатору собирая их айпи. Важным моментом в этой махинации является то, что установив сначала

TTL=1

, при каждом последующем запросе мы должны

увеличивать его на единицу

, чтобы очередной маршрутизатор передавал наш запрос на один шаг дальше. Когда запрос минуя все маршрутизаторы дойдёт до адресата, ошибка в поле

“Status”

структуры

ICMP_ECHO_REPLY

будет равна нулю, ..т.е. всё ок! В противном случае, там будет красоваться код

0x2B05 (11013) = IP_TTL_EXPIRED_TRANSIT

. Возможные варианты этого поля перечислены ниже:

Воспользовавшись этим нехитрым приёмом, мы можем написать свой

TRACERT

. Вообще, функционал любого кода зависит от конкретной задачи, поэтому я не стал тут выворачиваться наизнанку, и ограничился лишь выводом IP-адресов и времени прохождения пакета в обе стороны. Вот пример исходника, который вы можете заточить под себя..

C-подобный:

format pe console
entry start
include 'win32ax.inc'
;----------
.data
wsa WSADATA
echoReply ICMP_ECHO_REPLY
ipOpt IP_OPTIONS_INFO
capt db 13,10,' TRACERT example v0.1' db 13,10,' ******************************' db 13,10,' Host...: ',0
crlf db 13,10,0
ping db 13,10,' TTL= d d ms %s',0
succes db 13,10 db 13,10,' ~~~~~~' db 13,10,' TRACE successful..' db 13,10,' Press any key for exit...',0
frmt db '%s',0 ;
hndl dd 0 ;
addr dd 0 ;
errMes db 128 dup(0) ;
hostName db 64 dup(0) ;
;----------
.code
start:
;//---- Шапка и запрашиваем имя хоста ------ invoke WSAStartup,0x0101,wsa cinvoke printf,capt cinvoke scanf,frmt,hostName cinvoke printf,crlf
;//---- Вычисляем IP-адрес назначения ------ stdcall GetDestAddress ; (см.функцию в хвосте) mov [addr],eax ; запомнить его в переменной!
;//---- Создаём сессию и задаём опции ------ invoke IcmpCreateFile mov [hndl],eax mov [ipOpt.Ttl],1 ;// выставляем стартовый TTL=1 mov [ipOpt.Flags],IP_FLAG_DF ; флаг = не фрагментировать пакет
;//---- Стартуем трейс.. -------------------
@trace: mov eax,[addr] ; EAX = IP удалённого хоста invoke IcmpSendEcho,[hndl],eax,0,0, ; данных нет(0,0) ipOpt,echoReply,64,2000 ; тайм-аут =2 сек
;-- парсим приёмный буфер ------------------ mov eax,[echoReply.Address] ; EAX = IP отправителя invoke inet_ntoa,eax ; перевести его в строку mov ecx,[echoReply.RoundTripTime] ; ECX = время туда-обратно xor ebx,ebx ; mov bl,[ipOpt.Ttl] ; EBX = текущий TTL cinvoke printf,ping,ebx,ecx,eax ; вывод на экран! inc byte[ipOpt.Ttl] ;// Важно!!! TTL 1 cmp [echoReply.Status],0 ; проверить статут на SUCCESS! jnz @trace ; повторить, если не нуль..
;//---- Закругляемся.. --------------------- cinvoke printf,<' <--- %s',0>,hostName cinvoke printf,succes ; мессага "Всё ОК!" invoke IcmpCloseHandle,[hndl] ; прибить ECHO-сессию
@exit: cinvoke scanf,frmt,frmt 5 ; ждём нажатия клавиши.. invoke ExitProcess,0 ; на выход!
;//*****************************************
;//---- Вспомогательные функции
;//*****************************************
GetError: invoke WSAGetLastError invoke FormatMessage,0x1000,0,eax,0,errMes,128,0 invoke CharToOem,errMes,errMes cinvoke printf,errMes
ret
GetDestAddress: invoke inet_addr,hostName ;// это IP вида "127.0.0.1" ??? cmp eax,-1 ; 0xFFFFFFFF = ошибка jnz @ok ; если нет.. invoke gethostbyname,hostName ;// это имя типа "mail.ru" ??? or eax,eax ; 0 = ошибка jnz @name ; если No_Zero.. stdcall GetError ; иначе: встречаем её! pop eax ; jmp @exit ; на выход с ошибкой.
@name: ; юзер ввёл имя (не IP)
virtual at eax ; в EAX лежит адрес структуры "hostent"
host hostent ; определяем её как виртуальную
end virtual ; mov eax,[host.h_addr_list] ; берём из неё 4-байтный IP mov eax,[eax] ; ^^^ mov eax,[eax] ; ^^^
@ok: ret
;//--- Секция импорта ------
section '.idata' import data readable ;
library kernel32,'kernel32.dll', ; импортируемые библиотеки user32,'user32.dll', wsock32,'wsock32.dll', ; ^^^ msvcrt,'msvcrt.dll', ; ^^^ iphlp,'iphlpapi.dll' ; ^^^
import iphlp, IcmpSendEcho,'IcmpSendEcho',IcmpCreateFile,'IcmpCreateFile', IcmpCloseHandle,'IcmpCloseHandle'
import msvcrt, printf,'printf',scanf,'scanf'
include 'apikernel32.inc'
include 'apiuser32.inc'
include 'apiwsock32.inc'

На всякий/пожарный, в скрепке цепляю обновлённый вариант инклуд, в который добавил некоторые структуры и константы ошибок.

Характеристики

DCCP имеет встроенный механизм согласования параметров соединения, такой, как активные CCID для обоих полусоединений (см. рис. 3.12). Опции Change, Prefer и Confirm служат для согласования параметров. Change посылается с целью изменения определенного параметра.

Адресат может откликнуться, послав Prefer, где попросит партнера заменить значение параметра, или может изменить значение параметра и послать подтверждение Confirm. Надежность установления параметров обеспечивается повторной передачей, если это потребуется.