В заголовке маршрутизации IPv6 может появиться неограниченное количество адресов (реальное ограничение накладывается длиной пакета), а количество оставшихся сегментов не должно превышать количество адресов в заголовке. Документ RFC 2460 [27] описывает подробности обработки этого заголовка при пересылке его в направлении получателя. Там же вы можете найти подробно рассмотренный пример.
Заголовок маршрутизации обычно задается как вспомогательные данные в функции sendmsg
и возвращается в виде вспомогательных данных функцией recvmsg
. Для отправки заголовка приложению не требуется выполнять какие-либо специальные действия — достаточно просто указать его при вызове функции sendmsg
. Но для получения заголовка маршрутизации требуется, чтобы был включен параметр IPV6_RECVRTHDR
:
const int on = 1;
setsockopt(sockfd, IPPROTO_IPV6, IPV6_RECVRTHDR, &on, sizeof(on));
На рис. 27.8 показан формат объекта вспомогательных данных, используемый для отправки и получения заголовка маршрутизации. Для создания и обработки заголовка маршрутизации определены шесть функций. Следующие три функции используются для создания отправляемого параметра.
#include
socklen_t inet6_rth_space(int
void *inet6_rth_init(void *
int inet6_rth_add(void *
Возвращает: 0 в случае успешного выполнения, -1 в случае ошибки
Рис. 27.8. Объект вспомогательных данных для заголовка маршрутизации IPv6
Функция inet6_rth_space
возвращает количество байтов, необходимое для размещения объекта вспомогательных данных, содержащего заголовок маршрутизации указанного типа (обычно это IPV6_RTHDR_TYPE_0
) с заданным количеством сегментов.
Функция inet6_rth_init
инициализирует буфер, на который указывает аргумент rthbuf
, для помещения заголовка маршрутизации типа type и заданного количества сегментов. Возвращаемое значение этой функции — указатель на буфер. Этот указатель используется как аргумент при вызове следующей функции. Функция inet6_rth_init
возвращает NULL
в случае возникновения ошибок (например, при недостаточном размере предоставленного буфера).
Функция inet6_rth_add
добавляет адрес IPv6, на который указывает аргумент addr
, к концу составляемого заголовка маршрутизации. В случае успешного выполнения обновляется значение элемента segleft
заголовка маршрутизации, чтобы учесть добавленный новый адрес.
Следующие три функции манипулируют полученным заголовком маршрутизации:
#include
int inet6_rth_reverse(const void *
int inet6_rth_segments(const void *
struct in6_addr *inet6_rth_getaddr(const void *
Функция inet6_rth_reverse
принимает в качестве аргумента заголовок маршрутизации, полученный в виде объекта вспомогательных данных (на который указывает аргумент in
), и создает новый заголовок маршрутизации (в буфере, на который указывает аргумент out
), отправляющий дейтаграммы по обратному маршруту. Указатели in и out могут указывать на один и тот же буфер.
Функция inet6_rth_segments
возвращает количество сегментов в заголовке маршрутизации, на который указывает rthbuf
. В случае успешного выполнения функции возвращаемое значение оказывается больше 0.
Функция inet6_rth_getaddr
возвращает указатель на адрес IPv6, заданный через index
в заголовке маршрутизации rthbuf
. Аргумент index
должен лежать в пределах от 1 до значения, возвращенного функцией inet6_rth_segments
, включительно.