34. Протокол BOOTP: призначення, загальна характеристика, формат повідомлень.

BOOTP (англ. сокращение от Bootstrap Protocol) — сетевой протокол, используемый для автоматического получения клиентом IP-адреса. Это обычно происходит во время загрузки компьютера.

Формат пакета BOOTP

BOOTP запросы и отклики инкапсулируются в UDP датаграммы, как показано на рисунке 16.1.

http://www.soslan.ru/tcp/img/t16_1_2.gif

Рисунок 16.1 Инкапсуляция запросов и откликов BOOTP в UDP датаграмму.

 

На рисунке 16.2 приведен формат 300-байтного BOOTP запроса и отклика.

http://www.soslan.ru/tcp/img/t16_2_2.gif

Рисунок 16.2 Формат BOOTP запроса и отклика.

 

Код операции (opcode) равен 1 для запроса и 2 для отклика. Поле типа аппаратного адреса (hardware type) равно 1 для Ethernet 10 Мбит/сек, это же значение находится в поле с таким же именем в ARP запросе или отклике (см. рисунок 4.3). Длина аппаратного адреса (hardware address length) равна 6 байтам, как и для Ethernet.

Счетчик пересылок (hop count) устанавливается клиентом в 0, однако может быть использован уполномоченным сервером (описано в разделе "BOOTP через маршрутизаторы" этой главы).

Идентификатор транзакции (transaction ID) - 32-битное целое число, которое устанавливается клиентом и возвращается сервером. Оно позволяет клиенту сопоставить отклик с запросом. Клиент устанавливает в это поле случайное число для каждого запроса.

В поле количество секунд (number of seconds) клиент записывает время, когда он предпринял первую попытку загрузиться. На основании значения этого поля вторичный сервер делает вывод о том, что первичный сервер не доступен. (Вторичный сервер делает подобный вывод если величина в поле количества секунд достигла определенного значения.)

Если клиент уже знает свой IP адрес, он заполняет поле IP адрес клиента (client IP address). Есле нет - клиент устанавливает это значение в 0. В последнем случае сервер вставляет в поле ваш IP адрес (your IP address) IP адрес клиента. Поле IP адрес сервера (server IP address) заполняется сервером. Если используется уполномоченный сервер (раздел "BOOTP через маршрутизаторы" этой главы), он заполняет IP адрес шлюза (gateway IP address).

Клиент должен установить свой аппаратный адрес клиента (client hardware address). Это то же значение, которое находиться в заголовке Ethernet и в поле UDP датаграммы, благодаря чему оно становится доступным любому пользовательскому процессу (например, серверу BOOTP), который получил датаграмму. Обычно процессу, работающему с UDP датаграммами, сложно или практически невозможно определить значение, находящееся в поле заголовка Ethernet датаграммы, в которой передается UDP датаграмма.

Имя хоста сервера (server hostname) это строка, которая заполняется сервером (не обязательно). Сервер также может заполнить поле имени загрузочного файла (boot filename). В это поле заносится полный путь к файлу, который используется при загрузке.

Область производителя (vendor-specific) используется для различных расширений BOOTP. В разделе "Информация производителя" этой главы описываются некоторые из этих расширений.

Когда клиент стартует с использованием BOOTP (код операции равен 1), запрос обычно рассылается с помощью широковещательного сообщения канального уровня, при этом IP адрес назначения в IP заголовке обычно установлен в 255.255.255.255 (ограниченный широковещательный запрос, глава 12, раздел"Широковещательные запросы"). IP адрес источника - 0.0.0.0, так как клиент еще не знает своего IP адреса. Обратитесь к рисунку 3.9, где показано, что 0.0.0.0 это разрешенный IP адрес источника, используемый в момент загрузки источника.

Номера портов

Для BOOTP выделено два заранее известных порта: 67 для сервера и 68 для клиента. Это означает, что клиент не выбирает неиспользуемый динамически назначаемый порт, а использует порт номер 68. Причина, по которой были выбраны два номера портов, вместо того чтобы использовать только один для сервера, заключается в том, что сервер может отправить отклик (хотя обычно он этого не делает) широковещательным образом.

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

Если клиент воспользуется заранее известным портом сервера (67), все сервера в сети будут вынуждены просматривать каждый широковещательный отклик. (Если все сервера были "разбужены", им придется проверить код операции, определить, что это отклик, а не запрос, и снова "уснуть".) Поэтому выбор был остановлен на том, как все сделано сейчас, то есть клиент имеет свой собственный единственный заранее известный порт, который отличается от заранее известного порта сервера.

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

Сервер BOOTP

BOOTP клиент обычно "живет" в постоянной памяти бездисковой системы. Однако нам интересно посмотреть, как обычно реализуется сервер.

Во-первых, сервер читает UDP датаграммы с заранее известного порта (67). Специальных средств не требуется. В этом заключается отличие от RARP сервера (см. главу 5, раздел "Реализация RARP сервера"), который, как мы говорили, читает Ethernet фреймы, у которых в поле типа установлено "RARP запрос" (RARP request). Протокол BOOTP также позволяет серверу легко получить аппаратный адрес клиента, поместив его в BOOTP пакет (см. рисунок 16.2).

Тут возникает интересная проблема: как сервер может послать отклик непосредственно клиенту? Отклик находится в UDP датаграмме, и сервер знает IP адрес клиента (который обычно считывается из конфигурационного файла на сервере). Однако, если клиент отправил UDP датаграмму на этот IP адрес (это обычный способ обработки вывода UDP), хост сервера, возможно, выдаст ARP запрос для этого IP адреса. Однако, клиент не может ответить на ARP запрос, так как он еще не знает своего IP адреса! (Проблема подробно описана в RFC 951.)

Существует два решения. Первое, которое обычно используется в Unix серверах, заключается в том, что сервер выдает ioctl (2) запрос в ядро, чтобы поместить определенный пункт в ARP кэш для этого клиента. (Это как раз то, что делает команда arp -s, глава 4, раздел "Команда arp".) Сервер может так поступить, так как он знает аппаратный адрес клиента и его IP адрес. Это означает, что когда сервер посылает UDP датаграмму (BOOTP отклик), ARP модуль сервера может найти IP адрес клиента в ARP кэше.

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

BOOTP через маршрутизаторы

В разделе "Реализация RARP сервера" главы 5 мы сказали, что одним из неприятных свойств RARP является то, что он использует широковещательные запросы канального уровня, которые обычно не перенаправляются маршрутизаторами. А это означает, что необходимо иметь RARP сервер в каждой физической сети. BOOTP может работать через маршрутизатор, если маршрутизатор поддерживает этот протокол. (Большинство производителей маршрутизаторов добавляют поддержку этой характеристики.)

Обычно это необходимо для бездисковых маршрутизаторов, потому что если в качестве маршрутизатора используется многопользовательская система с диском, она может сама запустить BOOTP сервер. Однако все BOOTP сервера на основе Unix (приложение F) поддерживают этот режим, но, повторим снова, если Вы можете запустить BOOTP сервер в одной физической сети, нет необходимости перенаправлять запросы от другого сервера из другой сети.

Что произойдет, если маршрутизатор (также называемый "BOOTP агент" (BOOTP relay agent)) слушает BOOTP запросы на заранее известном порту сервера (67). Когда запрос принят, агент помещает свой IP адрес в поле IP адреса шлюза (gateway IP address) в BOOTP запросе и отправляет запрос на реальный BOOTP сервер. (Адрес, помещенный агентом в поле шлюза, это IP адрес интерфейса, на который был принят запрос.) Агент также увеличивает на единицу значение в поле пересылок. (Это делается для того, чтобы предотвратить зацикливание, если запрос будет повторно перенаправлен. В RFC 951 говориться, что запрос должен быть отброшен, если счетчик пересылок достигнет значения 3.) Так как исходящий запрос это датаграмма с персональным адресом (исходный запрос от клиента был широковещательным), он может пройти по любому маршруту к любому BOOTP серверу, проходя через другие маршрутизаторы. Реальный сервер получает запрос, формирует BOOTP отклик и отправляет его назад агенту, а не клиенту. Реальный сервер знает что запрос был перенаправлен, так как значение в поле шлюза ненулевое. Агент получает отклик и отправляет его клиенту.

 

Hosted by uCoz