Дополнительные команды ioctl

Предыдущая  Содержание  Следующая V*D*V

Мы уже видели, что для сокетов реализован системный вызов ioctl; SIOCSIFADDR и SIOCSIFMAP являются примерами "ioctl для сокетов". Теперь давайте посмотрим, как сетевым кодом используется третий аргумент системных вызовов.

 

Когда для сокета выполняется системный вызов ioctl, номер команды является одним из символов, определенных в <linux/sockios.h> и функция sock_ioctl вызывает непосредственно зависимую от протокола функцию (где "протокол" относится к основным используемым сетевым протоколам, например, IP или AppleTalk).

 

Любая команда ioctl, которая не распознана уровнем протокола, передаётся на уровень устройства. Эти относящиеся к устройству команды ioctl принимают третий аргумент от пользовательского пространства, struct ifreq *. Эта структура определена в <linux/if.h>.  Команды SIOCSIFADDR и SIOCSIFMAP работают фактически со структурой ifreq. Дополнительный аргумент для SIOCSIFMAP, хотя и определяется как ifmap, является лишь полем ifreq.

 

В дополнение к использованию стандартизированных вызовов, каждый интерфейс может определить свои собственные команды ioctl. Интерфейс plip, например, позволяет через ioctl изменять свои внутренние значения таймаутов. Реализация ioctl для сокетов  распознаёт 16 команд, как предназначенные для интерфейса: от SIOCDEVPRIVATE до SIOCDEVPRIVATE+15. (* Обратите внимание, что согласно <linux/sockios.h> такие SIOCDEVPRIVATE команды являются устаревшими. Чем их следует заменить, однако, не ясно и многочисленные драйверы в дереве исходных кодов всё ещё их используют.)

 

Когда одна из этих команд распознана, в соответствующем драйвере интерфейса вызывается dev->do_ioctl. Функция получает тот же указатель struct ifreq *, который использует функция ioctl общего назначения:

 

int (*do_ioctl)(struct net_device *dev, struct ifreq *ifr, int cmd);

 

Указатель ifr сообщает пространству ядра адрес, который хранит копию структуры, переданной пользователем. После возвращения do_ioctl, структура копируется обратно в пространство пользователя; таким образом, драйвер может использовать   свои команды для получения и возвращения данных. Зависимые от устройства команды могут захотеть использовать поля в struct ifreq, но они уже содержат стандартизированные значения и маловероятно, что драйвер сможет адаптировать эту структуру под свои потребности. Поле ifr_data является объектом caddr_t (указателем), который предназначен для использования под потребности данного устройства. Драйвер и программа, используемая для вызова команд ioctl, должны договориться об использовании ifr_data. Например, pppstats использует зависящие от устройства команды для получения информации от драйвера интерфейса ppp.

 

Не стоит здесь показывать реализацию do_ioctl, но с информацией этой главы и примерами ядра вы должны суметь её написать, когда вам это потребуется. Однако, следует отметить, что реализация в plip использует ifr_data некорректно и её не следует использовать в качестве примера для реализации ioctl.

Предыдущая  Содержание  Следующая