TCP-IP крупным планом

         

Примеры широковещательных запросов



Примеры широковещательных запросов

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

Во-первых, приложение должно поддерживать широковещательные запросы. Если мы запустим

sun % ping 255.255.255.255
/usr/etc/ping: unknown host 255.255.255.255

то есть постараемся послать запрос на локальный кабель, это не сработает. Однако проблема здесь заключена в самом приложении (ping). Большинство приложений, которые воспринимают как цифровые IP адреса (в десятичном выражении), так и имена хостов, вызывают функцию inet_addr (3), чтобы конвертировать строку чисел в 32-битный двоичный IP адрес, и если это не удалось, воспринимают строку символов как имя хоста. Эта библиотечная функция возвращает код ошибки -1 если в строке обнаружен символ, отличный от цифры или десятичной точки, в случае ограниченного широковещательного адреса (255.255.255.255) также выдается код -1. Большинство программ, которые воспринимают символьную строку как имя хоста, обрабатывают его с использованием DNS (глава 14) и ограничиваются выводом ошибки, такой как "неизвестный хост" (unknown host).

Даже если мы исправим эту ошибку в программе ping, результаты будут все равно не такими как хотелось бы. Из шести протестированных систем, только одна генерировала широковещательные пакеты в локальный кабель. Большинство ищут IP адрес 255.255.255.255 в таблице маршрутизации, в конце концов находят маршрут по умолчанию и посылают персональный пакет на маршрутизатор по умолчанию. Естественно, такой пакет уничтожается.

В подобном случае необходимо использовать широковещательные запросы, направленные в подсеть. И действительно, в разделе "ICMP запрос и отклик маски адреса" главы 6 мы посылали датаграммы на IP адрес 140.252.13.63 для нижнего Ethernet в нашей тестовой сети и получали отклики от всех хостов Ethernet. Широковещательный адрес, направленный в подсеть, соответствует каждому интерфейсу, именно этот адрес используется командой ifconfig (глава 3, раздел "Команда ifconfig"). Если мы пошлем ping на этот адрес, результат будет таким, как мы хотели:

sun % arp -a ARP кэш пуст

sun % ping 140.252.13.63
PING 140.252.13.63: 56 data bytes
64 bytes from sun (140.252.13.33): icmp_seq=0. time=4. ms
64 bytes from bsdi (140.252.13.35): icmp_seq=0. time=172. ms
64 bytes from svr4 (140.252.13.34): icmp_seq=0. time=192. ms

64 bytes from sun (140.252.13.33): icmp_seq=1. time=1. ms
64 bytes from bsdi (140.252.13.35): icmp_seq=1. time=52. ms
64 bytes from svr4 (140.252.13.34): icmp_seq=1. time=90. ms

^? введен символ прерывани
----140.252.13.63 PING Statistics----
2 packets transmitted, 6 packets received, -200% packet loss
round-trip (ms) min/avg/max = 1/85/192

sun % arp -a снова проверяем ARP кэш
svr4 (140.252.13.34) at 0:0:c0:c2:9b:26
bsdi (140.252.13.35) at 0:0:c0:6f:2d:40

IP определяет, что адрес назначения (140.252.13.63) - это широковещательный адрес, направленный в подсеть, и посылает датаграммы на широковещательный адрес канального уровня.

Мы упоминали в разделе "ICMP запрос и отклик маски адреса" главы 6, что этот тип широковещательных запросов означает обращение ко всем хостам локальной сети, включая отправителя. Из примера видно, что мы получили отклик от отправляющего хоста sun и от всех остальных хостов, находящихся на кабеле.

В этом примере показан ARP кэш перед и после того, как был запущен ping на широковещательный адрес. Это сделано для того, чтобы показать взаимосвязь между рассылкой широковещательных запросов и состоянием ARP. ARP кэш пуст перед запуском ping, и заполнен по окончании. (В кэше находится по одной записи на каждый хост, находящийся на кабеле и ответивший на эхо запрос.) Как заполнился кэш, раз мы сказали, что Ethernet фрейм посылается на широковещательный адрес канального уровня 0xffffffff? Отправка этих фреймов хостом sun не требует ARP.

Если мы посмотрим работу ping с использованием tcpdump, то увидим, что получатели широковещательных фреймов генерируют ARP запрос на sun, перед тем как отправить отклик. Причем, надо отметить, что каждый отклик персональный. Мы говорили в разделе "Примеры ARP" главы 4, что получатель ARP запроса (sun в данном примере) обычно добавляет IP адрес и аппаратный адрес запрашивающего в свой ARP кэш, и отправляет ARP отклик. Это делается из предположения, что если запрашивающий послал нам пакет, мы, возможно, в будущем захотим послать что-нибудь и ему.

Использование ping - это особый случай, потому что подобный тип программного интерфейса, (который в большинстве Unix реализаций называется "символьный сокет" (raw socket)), всегда позволяет послать датаграмму на широковещательный адрес. Что если мы воспользуемся приложением, которое не поддерживает широковещательные запросы, как, например, TFTP? (Мы опишем TFTP более подробно в главе 15.)


bsdi % tftp запускаем клиента
tftp> connect 140.252.13.63 указываем IP адрес сервера
tftp> get temp.foo и пытаемся получить файл с сервера
tftp: sendto: Permission denied
tftp> quit прекращение работы клиента

Здесь мы получаем ошибку мгновенно, при этом в кабель ничего не посылается. Это объясняется тем, что сокеты API не позволяют процессу отправлять UDP датаграммы на широковещательный адрес, если процесс специально не заявил, что он планирует использовать широковещательные запросы. Это сделано для того, чтобы предотвратить ошибочное указание широковещательного адреса пользователем (именно так, как поступили мы в данном случае), тогда как приложение не предназначено для рассылки широковещательных запросов.

Для сокет API, приложение должно установить опцию сокет SO_BROADCAST перед отправкой UDP датаграммы на широковещательный адрес. Однако, не все системы применяют это ограничение. Некоторые реализации позволяют любому процессу отправлять UDP датаграммы широковещательным образом, причем не требуют от процесса, чтобы он объявлял об этом. Другие имеют более строгие ограничения и требуют, чтобы процесс имел привилегии суперпользователя, чтобы использовать широковещательную рассылку.

Следующий вопрос заключается в том, перенаправляются ли широковещательные пакеты. Некоторые ядра и маршрутизаторы имеют опцию, которая позволяет включить или выключить эту характеристику. (См. приложение Е.)

Если мы включим характеристику перенаправления широковещательных пакетов на маршрутизаторе bsdi и запустим ping с хоста slip, то увидим, что bsdi перенаправляет широковещательные запросы, направленные в подсеть. Перенаправление направленных широковещательных запросов означает, что маршрутизатор воспринимает входящие датаграммы как персональные, определяет, что адрес назначения это направленный широковещательный адрес одного из его интерфейсов, и затем перенаправляет датаграммы в соответствующую сеть, используя широковещательный адрес канального уровня.


slip % ping 140.252.13.63
PING 140.252.13.63 (140.252.13.63): 56 data bytes
64 bytes from 140.252.13.35: icmp_seq=0 ttl=255 time=190 ms
64 bytes from 140.252.13.33: icmp_seq=0 ttl=254 time=280 ms (DUP!)
64 bytes from 140.252.13.34: icmp_seq=0 ttl=254 time=360 ms (DUP!)

64 bytes from 140.252.13.35: icmp_seq=1 ttl=255 time=190 ms
64 bytes from 140.252.13.33: icmp_seq=1 ttl=254 time=270 ms (DUP!)
64 bytes from 140.252.13.34: icmp_seq=1 ttl=254 time=360 ms (DUP!)

^? введен символ прерывания
--- 140.252.13.63 ping statistics ---
3 packets transmitted, 2 packets received, +4 duplicates, 33% packet loss
round-trip min/avg/max = 180/273/360 ms

Мы видим, что это работает. Также мы видим, что программа ping в BSD проверяет отслеживает повторные номера последовательности и помечает их как DUP!. Это обычно означает, что пакет был каким-либо образом продублирован, однако здесь именно это и должно было произойти, так как запросы были отправлены на широковещательный адрес.

Этот тест можно запустить с более удаленного хоста (от той сети, к которой направляется широковещательный запрос). Мы запустили ping с хоста vangogh.cs.berkeley.edu (который находится на расстоянии 14 пересылок от нашей сети), и это также будет работать, если маршрутизатор sun сконфигурирован таким образом, чтобы перенаправлять направленные широковещательные запросы. В данном случае IP датаграммы (переносящие ICMP эхо запросы) перенаправляются каждым маршрутизатором, встречающимся им на пути, как обычные датаграммы. Никто из них не знает, что в действительности это направленные широковещательные запросы. И последний маршрутизатор, netb, думает, что пакеты предназначены хосту с идентификатором равным 63, и перенаправляет их на sun. В этом месте sun определяет, что IP адрес назначения в действительности это широковещательный адрес подключенного интерфейса, и передает датаграммы в виде широковещательных запросов канального уровня для этой сети.

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



Содержание раздела