KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Программное обеспечение » Уильям Стивенс - UNIX: разработка сетевых приложений

Уильям Стивенс - UNIX: разработка сетевых приложений

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Уильям Стивенс, "UNIX: разработка сетевых приложений" бесплатно, без регистрации.
Перейти на страницу:

Элемент sdl_data содержит и имя, и адрес канального уровня (например, 48-разрядный MAC-адрес интерфейса Ethernet). Имя начинается с sdl_data[0] и не заканчивается нулем. Начало адреса канального уровня смещено на sdl_nlen байтов относительно начала имени. В этом заголовочном файле для возвращения указателя на адрес канального уровня задается следующий макрос:

#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))

Эти структуры адреса сокета имеют переменную длину [128, с. 89]. Если адрес канального уровня и имя превышают 12 байт, размер структуры будет больше 20 байт. В 32-разрядных системах размер обычно округляется в большую сторону, до следующего числа, кратного 4 байтам. Мы также увидим на рис. 22.1, что когда одна из этих структур возвращается параметром сокета IP_RECVIF, все три длины становятся нулевыми, а элемента sdl_data не существует.

18.3. Чтение и запись

Создав маршрутизирующий сокет, процесс может отправлять ядру команды путем записи в этот сокет и считывать из него информацию от ядра. Существует 12 различных команд маршрутизации, 5 из которых могут быть запущены процессом. Они определяются в заголовочном файле <net/route.h> и показаны в табл. 18.1.


Таблица 18.1. Типы сообщений, проходящих по маршрутизирующему сокету

Тип сообщения К ядру? От ядра? Описание Тип структуры RTM_ADD • • Добавить маршрут rt_msghdr RTM_CHANGE • • Поменять шлюз, метрику или флаги rt_msghdr RTM_DELADDR • Адрес был удален из интерфейса ifa_msghdr RTM_DELETE • • Удалить маршрут rt_msghdr RTM_GET • • Сообщить о метрике и других характеристиках маршрута rt_msghdr RTM_IFINFO • Находится ли интерфейс в активном состоянии if_msghdr RTM_LOCK • • Блокировка указанной метрики rt_msghdr RTM_LOSING • Возможно, неправильный маршрут rt_msghdr RTM_MISS • Поиск этого адреса завершился неудачно rt_msghdr RTM_NEWSDDR • Адрес добавлен к интерфейсу ifa_msghdr RTM_NEWMDDR • Групповой адрес добавлен к интерфейсу ifma_msghdr RTM_REDIRECT • Ядро получило указание использовать другой маршрут rt_msghdr RTM_RESOLVE • Запрос на определение адреса канального уровня по адресу получателя rt_msghdr

На маршрутизирующем сокете происходит обмен пятью различными структурами, как показано в последнем столбце таблицы: rt_msghdr, if_msghdr, if_announcemsghdr, ifma_msghdr и ifa_msghdr. Эти структуры представлены в листинге 18.2.


Листинг 18.2. Пять структур, возвращаемых с маршрутизирующими сообщениями

struct rt_msghdr { /* из <net/route.h> */

 u_short rtm_msglen;  /* для пропуска некорректных сообщений */

 u_char  rtm_version; /* для обеспечения двоичной совместимости в будущем */

 u_char  rtm_type;    /* тип сообщения */


 u_short rtm_index; /* индекс интерфейса, с которым связан адрес */

 int     rtm_flags; /* флаги */

 int     rtm_addrs; /* битовая маска, идентифицирующая sockaddr (структуру адреса

                       сокета) в msg */

 pid_t   rtm_pid;   /* идентификация отправителя */

 int     rtm_seq;   /* для идентификации действия отправителем */

 int     rtm_errno; /* причина неудачного выполнения */

 int     rtm_use;   /* из rtentry */

 u_long  rtm_inits; /* какую метрику мы инициализируем */

 struct rt_metrics rtm_rmx; /* сами метрики */

};


struct if_msghdr { /* из <net/if.h> */

 u_short ifm_msglen;  /* для пропуска некорректных сообщений */

 u_char  ifm_version; /* для обеспечения двоичной совместимости в будущем */

 u_char  ifm_type;    /* тип сообщения */


 int     ifm_addrs;       /* как rtm_addrs */

 int     ifm_flags;       /* значение if_flags */

 u_short ifm_index;       /* индекс интерфейса, с которым связан адрес */

 struct if_data ifm_data; /* статистические и другие сведения */

};


struct ifa_msghdr { /* из <net/if.h> */

 u_short ifam_msglen;  /* для пропуска некорректных сообщений */

 u_char  ifam_version; /* для обеспечения двоичной совместимости в будущем */

 u_char  ifam_type;    /* тип сообщения */


 int     ifam_addrs;  /* как rtm_addrs */

 int     ifam_flags;  /* значение ifa_flags */

 u_short ifam_index;  /* индекс интерфейса, с которым связан адрес */

 int     ifam_metric; /* значение ifa_metric */

};


struct ifma_msghdr { /* из <net/if.h> */

 u_short ifmam_msglen;  /* для пропуска некорректных сообщений */

 u_char  ifmam_version; /* для обеспечения двоичной совместимости в будущем */

 u_char  ifmam_type;    /* тип сообщения */

 int     ifmam_addrs;   /* аналог rtm_addrs */

 int     ifmam_flags;   /* значение ifa_flags */

 u_short ifmam_index;   /* индекс связанного ifp */

};


struct if_announcemsghdr { /* из <net/if.h> */

 u_short ifan_msglen;  /* для пропуска некорректных сообщений */

 u_char  ifan_version; /* для обеспечения двоичной совместимости в будущем */

 u_char  ifan_type;    /* тип сообщения */

 u_short ifan_index;   /* индекс связанного ifp */

 char    ifan_name[IFNAMSIZ]; /* название интерфейса, напр. "en0" */

 u_short ifan_what;    /* тип объявления */

};

Первые три элемента каждой структуры одни и те же: длина, версия и тип сообщения. Тип — это одна из констант из первого столбца табл. 18.1. Элемент длины xxx_msglen позволяет приложению пропускать типы сообщений, которые оно не распознает.

Элементы rtm_addrs, ifm_addrs и ifam_addrs являются битовыми масками, указывающими, какая из возможных восьми структур адреса сокета следует за сообщением. В табл. 18.2 показаны константы и значения для битовой маски, определяемые в заголовочном файле <net/route.h>.


Таблица 18.2. Константы, используемые для ссылки на структуры адреса сокета в маршрутизирующих сообщениях

Битовая маска, константа Битовая маска, значение Индекс массива, константа Индекс массива, значение Структура адреса сокета содержит RTA_DST 0x01 RTAX_DST 0 Адрес получателя RTA_GATEWAY 0x02 RTAX_GATEWAY 1 Адрес шлюза RTA_NETMASK 0x04 RTAX_NETMASK 2 Маска сети RTA_GENMASK 0x08 RTAX_GENMASK 3 Маска клонирования RTA_IFP 0x10 RTAX_IFP 4 Имя интерфейса RTA_IFA 0x20 RTAX_IFA 5 Адрес интерфейса RTA_AUTHOR 0x40 RTAX_AUTHOR 6 Отправитель запроса на перенаправление RTA_BRD 0x80 RTAX_BRD 7 Адрес получателя типа «точка-точка» или широковещательный RTAX_MAX 8 Максимальное количество элементов

В том случае, когда имеется множество структур адреса сокета, они всегда располагаются в порядке, показанном в таблице.

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*