UNIX: разработка сетевых приложений
Функция
аналогична предыдущей функции, но позволяет вызывающему процессу задать тип параметра, который следует искать (аргумент type), вместо того чтобы каждый раз возвращать следующий параметр.inet6_opt_findФункция
предназначена для извлечения значений из параметра по указателюinet6_opt_get_val, возвращаемому предшествующим вызовомdatabufилиinet6_opt_next. Как и дляinet6_opt_find, аргументinet6_opt_set_valдолжен начинаться с 0 для каждого параметра, а затем должен приравниваться значению, возвращаемому предшествующим вызовомoffset.inet6_opt_get_val27.6. Заголовок маршрутизации IPv6
Заголовок маршрутизации IPv6 используется для маршрутизации от отправителя в IPv6. Первые два байта заголовка маршрутизации такие же, как показанные на рис. 27.3: поле следующего заголовка (next header) и поле длины заголовка расширения (header extension length). Следующие два байта задают тип маршрутизации (routing type) и количество оставшихся сегментов (number of segments left) (то есть сколько из перечисленных узлов еще нужно пройти). Определен только один тип заголовка маршрутизации, обозначаемый как тип 0. Формат заголовка маршрутизации показан на рис. 27.7.
Рис. 27.7. Заголовок маршрутизации IPv6
В заголовке маршрутизации IPv6 может появиться неограниченное количество адресов (реальное ограничение накладывается длиной пакета), а количество оставшихся сегментов не должно превышать количество адресов в заголовке. Документ RFC 2460 [27] описывает подробности обработки этого заголовка при пересылке его в направлении получателя. Там же вы можете найти подробно рассмотренный пример.
Заголовок маршрутизации обычно задается как вспомогательные данные в функции
и возвращается в виде вспомогательных данных функциейsendmsg. Для отправки заголовка приложению не требуется выполнять какие-либо специальные действия — достаточно просто указать его при вызове функцииrecvmsg. Но для получения заголовка маршрутизации требуется, чтобы был включен параметрsendmsg:IPV6_RECVRTHDRconst int on = 1;setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));На рис. 27.8 показан формат объекта вспомогательных данных, используемый для отправки и получения заголовка маршрутизации. Для создания и обработки заголовка маршрутизации определены шесть функций. Следующие три функции используются для создания отправляемого параметра.
#include <netinet/in.h>socklen_t inet6_rth_space(int <i>type</i>, int <i>segments</i>);<i>Возвращает: положительное число, равное количеству байтов в случае успешного выполнения, 0 в случае ошибки</i>void *inet6_rth_init(void *<i>rthbuf</i>, socklen_t <i>rthlen</i>, int <i>type</i>, int <i>segments</i>);<i>Возвращает: непустой указатель в случае успешного выполнения, NULL в случае ошибки</i>int inet6_rth_add(void *<i>rthbuf</i>, const struct in6_addr *<i>addr</i>);Возвращает: 0 в случае успешного выполнения, -1 в случае ошибкиРис. 27.8. Объект вспомогательных данных для заголовка маршрутизации IPv6
Функция
возвращает количество байтов, необходимое для размещения объекта вспомогательных данных, содержащего заголовок маршрутизации указанного типа (обычно этоinet6_rth_space) с заданным количеством сегментов.IPV6_RTHDR_TYPE_0Функция
инициализирует буфер, на который указывает аргументinet6_rth_init, для помещения заголовка маршрутизации типа type и заданного количества сегментов. Возвращаемое значение этой функции — указатель на буфер. Этот указатель используется как аргумент при вызове следующей функции. Функцияrthbufвозвращаетinet6_rth_initв случае возникновения ошибок (например, при недостаточном размере предоставленного буфера).NULLФункция
добавляет адрес IPv6, на который указывает аргументinet6_rth_add, к концу составляемого заголовка маршрутизации. В случае успешного выполнения обновляется значение элементаaddrзаголовка маршрутизации, чтобы учесть добавленный новый адрес.segleftСледующие три функции манипулируют полученным заголовком маршрутизации:
#include <netinet/in.h>int inet6_rth_reverse(const void *<i>in</i>, void *<i>out</i>);<i>Возвращает: 0 в случае успешного выполнения, -1 в случае ошибки</i>int inet6_rth_segments(const void *<i>rthbuf</i>);<i>Возвращает: количество сегментов в заголовке маршрутизации в случае успешного выполнения, -1 в случае ошибки</i>struct in6_addr *inet6_rth_getaddr(const void *<i>rthbuf</i>, int <i>index</i>);<i>Возвращает: непустой указатель в случае успешного выполнения, NULL в случае ошибки</i>Функция
принимает в качестве аргумента заголовок маршрутизации, полученный в виде объекта вспомогательных данных (на который указывает аргументinet6_rth_reverse), и создает новый заголовок маршрутизации (в буфере, на который указывает аргументin), отправляющий дейтаграммы по обратному маршруту. Указатели in и out могут указывать на один и тот же буфер.outФункция
возвращает количество сегментов в заголовке маршрутизации, на который указываетinet6_rth_segments. В случае успешного выполнения функции возвращаемое значение оказывается больше 0.rthbufФункция
возвращает указатель на адрес IPv6, заданный черезinet6_rth_getaddrв заголовке маршрутизацииindex. Аргументrthbufдолжен лежать в пределах от 1 до значения, возвращенного функциейindex, включительно.inet6_rth_segments

