17.9. Операции с таблицей маршрутизации
Для работы с таблицей маршрутизации предназначены два вызова функции ioctl
. Эти два вызова требуют, чтобы третий аргумент функции ioctl был указателем на структуру rtentry
, которая определяется в заголовочном файле . Обычно эти вызовы исходят от программы route
. Их может делать только привилегированный пользователь. При наличии маршрутизирующих сокетов (глава 18) для выполнения этих запросов используются именно они, а не функция ioctl
.
■ SIOCADDRT
. Добавить запись в таблицу маршрутизации.
■ SIOCDELRT
. Удалить запись из таблицы маршрутизации.
Нет способа с помощью функции ioctl
перечислить все записи таблицы маршрутизации. Эту операцию обычно выполняет программа netstat
с флагом -r
. Программа получает таблицу маршрутизации, считывая память ядра ( /dev/kmem
). Как и в случае с просмотром кэша ARP, в разделе 18.4 мы увидим более простой (и предпочтительный) способ, предоставляемый функцией sysctl
.
Команды функции ioctl
, используемые в сетевых приложениях, можно разделить на шесть категорий:
1. Операции с сокетами (находимся ли мы на отметке внеполосных данных?).
2. Операции с файлами (установить или сбросить флаг отсутствия блокировки).
3. Операции с интерфейсами (возвратить список интерфейсов, получить широковещательный адрес).
4. Операции с кэшем ARP (создать, изменить, получить, удалить).
5. Операции с таблицей маршрутизации (добавить или удалить).
6. Операции с потоками STREAMS (см. главу 31).
Мы будем использовать операции с сокетами и файлами, а получение списка интерфейсов — это настолько типичная операция, что для этой цели мы разработали собственную функцию. Мы будем применять ее много раз в оставшейся части книги. Вызовы функции ioctl
с кэшем ARP и таблицей маршрутизации используются лишь несколькими специализированными программами.
1. В разделе 17.7 мы сказали, что широковещательный адрес, возвращаемый запросом SIOCGIFBRDADDR, возвращается в элементе ifr_broadaddr
. Но на с. 173 [128] сказано, что он возвращается в элементе ifr_dstaddr
. Имеет ли это значение?
2. Измените программу get_ifi_info
так, чтобы она делала первый вызов SIOCGIFCONF
для одной структуры ifreq
, а затем каждый раз в цикле увеличивайте длину на размер одной из этих структур. Затем поместите в цикл операторы, которые выводили бы размер буфера при каждом вызове независимо от того, возвращает функция ioctl
ошибку или нет, и при успешном выполнении выведите возвращаемую длину буфера. Запустите программу prifinfo
и посмотрите, как ваша система обрабатывает вызов, когда размер буфера слишком мал. Выведите также семейство адресов для всех возвращаемых структур, семейство адресов которых не совпадает с указанным в первом аргументе функции get_ifi_info
, чтобы увидеть, какие еще структуры возвращает ваша система.
3. Измените функцию get_ifi_info
так, чтобы она возвращала информацию об адресе с альтернативным именем, если дополнительный адрес находится не в той подсети, в которой находится предыдущий адрес для данного интерфейса. Таким образом, наша версия из раздела 17.6 будет игнорировать альтернативные имена в диапазоне от 206.62.226.44 до 206.62.226.46, и это вполне нормально, поскольку они находятся в той же подсети, что и первичный адрес интерфейса 206.62.226.33. Но если альтернативное имя находится в другой подсети, допустим 192.3.4.5, возвратите структуру ifi_info
с информацией о дополнительном адресе.
4. Если ваша система поддерживает вызов SIOCGIGNUM
функции ioctl
, измените листинг 17.4 так, чтобы запустить этот вызов, и используйте возвращаемое значение как начальный размер буфера.
Глава 18
Маршрутизирующие сокеты
Традиционно доступ к таблице маршрутизации Unix внутри ядра осуществлялся с помощью команд функции ioctl
. В разделе 17.9 мы описали две операции: SIOCADDRT
и SIOCDELRT
, предназначенные для добавления и удаления маршрута. Мы также отметили, что не существует операции чтения всей таблицы маршрутизации — вместо этого программы, такие как netstat
, считывают память ядра, для того чтобы получить содержимое таблицы маршрутизации. И еще одно добавление. Демонам маршрутизации, таким как gated
, необходимо отслеживать сообщения ICMP (Internet Control Message Protocol — протокол управляющих сообщений Интернета) об изменении маршрутов, получаемых ядром, и для этого они часто создают символьный (неструктурированный) сокет ICMP (см. главу 28), а затем прослушивают на этом сокете все получаемые сообщения ICMP.
Читать дальше
Конец ознакомительного отрывка
Купить книгу