Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #30, МАЙ 2003 г.

Ping Master - трансляция cmd2html на ASP

Владимир Егоров aka Dr.NET

Спецвыпуск Xakep, номер #030, стр. 030-050-4


Something else

А теперь попробуем написать свой упрощенный вариант пинга, который будет выводить только информацию о том, получен ли ответ от интересующего нас хоста или нет. Фактически, для получения этой информации достаточно отправить хосту-адресату эхо-запрос ICMP (Internet Control Message Protocol, протокол для передачи различных сообщений между узлами, чаще всего - сообщений об ошибках). После этого нужно подождать ответа и чуть-чуть шевельнуть мозгом. На основе проделанного следует сделать вывод о том, доступен узел или нет. Эту консольную программку я написал также на C#.

Для начала создаем новый текстовый файл с именем "ping.cs". В нем сначала описываем, какие пространства имен будут импортированы (директива "using"). Импортируем "System", "System.Net", "System.Net.Sockets" и "System.Text.RegularExpressions". Далее задаем свое пространство имен, к которому будет принадлежать созданный нами класс "Ping". Для этого пишем после слова "namespace" название пространства имен, например, "Custom". Далее задаем класс "Ping". В нем будет всего три статических метода: "checksum_ip(byte[] buffer)", "send_echo(IPAddress ip_to, int timeout)" и "Main(string[] args)". Первый метод производит вычисление контрольной суммы для заголовка IP, второй отправляет эхо-запрос, а третий - это входная точка нашей проги.

Для отправки запроса нам самим придется полностью сформировать IP-пакет и отправить его при помощью низкоуровневого сокета. Структура заголовка IP, который нам предстоит сформировать, включает следующие поля (по порядку): 4 бита версии IP, 4 бита длины заголовка, 8 бит TOS (тип службы), полная длина в байтах - 16 бит, идентификатор - 16 бит, три однобитных флага, смещение фрагмента данных - 13 бит, 8 бит TTL (время жизни), 8 бит типа протокола, 16-битная контрольная сумма заголовка, 32-битный IP-адрес отправителя, 32-битный IP-адрес получателя. После этого должны идти параметры IP (необязательно), а дальше - сами данные. В качестве данных запишем только ICMP-заголовок, включающий 8-битный тип ICMP, 8-битный код ICMP, 16-битную контрольную сумму ICMP.

Понимаю внезапно постигшую тебя дрожь :). Расслабься, сейчас все немного упростим. Во-первых, в качестве идентификатора IP возьмем фиксированное число, во-вторых, поскольку нам нужен будет тип ICMP, равный 8 (эхо-запрос), и код ICMP, равный 0, то мы можем сформировать неизменяемый заголовок ICMP, подсчитав его контрольную сумму (это 16-битная комплиментарная сумма байт в сообщении ICMP). То есть получается, что единственными изменяемыми полями в нашем сообщении будут IP-адрес отправителя, IP-адрес получателя и контрольная сумма.

Сумма

Вычисление контрольной суммы IP будем проводить с помощью метода "checksum_ip". Отличие от вычисления контрольной суммы ICMP состоит в том, что здесь складываются не байты, а слова (2 байта, если не знал). Длина заголовка - вторые 4 бита в заголовке IP (длина в 32-битных словах), поэтому длину заголовка вычисляем так: "int hdr_length = (buffer[0]&0x000f)*4". После суммирования, в случае переполнения, прибавляем "лишние" биты к усеченному до 16 бит результату и находим комплиментарное дополнение.

Назад на стр. 030-050-3  Содержание  Вперед на стр. 030-050-5