Возвращает: длину законченного заголовка расширения, -1 в случае ошибки
int inet6_opt_set_val(void * databuf, int offset,
const void * val, socklen_t vallen);
Возвращает: новое смещение в буфере databuf
Функция
inet6_opt_init
возвращает количество байтов, необходимое для данного параметра. Если аргумент
extbuf
не является нулевым указателем, функция инициализирует заголовок расширения. Значение -1 возвращается при аварийном завершении работы в том случае, если аргумент
extlen
не кратен 8. (Все заголовки параметров
транзитных узлов и получателя в IPv6 должны быть кратны 8.)
Функция
inet6_opt_append
возвращает общую длину заголовка расширения после добавления указанного при вызове параметра. Если аргумент
extbuf
не является нулевым указателем, функция дополнительно выполняет инициализацию параметра и вставляет необходимое заполнение. Значение -1 возвращается в случае аварийного завершения работы, если параметр не помещается в выделенный буфер. Аргумент
offset
представляет собой текущую полную длину, то есть значение, возвращенное при предыдущем вызове
inet6_opt_append
или
inet6_opt_init
. Аргументы
type
и
len
задают тип и длину параметра, они копируются непосредственно в его заголовок. Аргумент
align
указывает условие выравнивания, то есть значение x из выражения xn + y. Значение у вычисляется по
align
и
len
, поэтому указывать его явным образом необходимости нет. Аргумент
databufp
представляет собой адрес будущего указателя на значение параметра. Значение параметра копируется вызывающим процессом при помощи функции
inet6_opt_set_val
или любым другим методом.
Для завершения расширяющего заголовка вызывается функция
inet6_opt_finish
, которая добавляет в заголовок заполнение, делая его длину кратной 8 байтам. Как и раньше, заполнение добавляется в буфер только в том случае, если аргумент
extbuf
представляет собой непустой указатель. В противном случае функция вычисляет обновленное значение длины. Подобно
inet6_opt_append
, аргумент
offset
задает текущую полную длину (значение, возвращаемое
inet6_opt_append
и
inet6_opt_init
). Функция
inet6_opt_finish
возвращает полную длину возвращаемого заголовка или -1, если требуемое заполнение не помещается в предоставленный буфер.
Функция
inet6_opt_set_val
копирует значение параметра в буфер данных, возвращаемый
inet6_opt_append
. Аргумент
databuf
представляет собой указатель, возвращаемый
inet6_opt_append
. Аргумент
offset
представляет собой текущую длину внутри параметра, его необходимо инициализировать нулем для каждого параметра, а затем использовать возвращаемые
inet6_opt_set_val
значения по мере построения параметра. Аргументы
val
и
vallen
определяют значение для копирования в буфер значения параметра.
Предполагается, что с помощью этих функций вы будете делать два прохода по списку параметров, которые вы предполагаете вставить: во время первого прохода будет вычисляться требуемая длина буфера, а во время второго прохода — выполняться фактическое построение буфера параметра. При первом проходе нужно вызвать
inet6_opt_init
,
inet6_opt_append
(один раз для каждого параметра) и
inet6_opt_finish
, передавая нулевой указатель и 0 в качестве аргументов
extbuf
и
extlen
соответственно. Затем можно динамически выделить буфер, использовав в качестве размера значение, возвращенное
inet6_opt_finish
. Этот буфер будет передаваться в качестве аргумента
extbuf
при втором проходе. Во время второго прохода вызываются функции
inet6_opt_init
и
inet6_opt_append
. Копирование значений параметров может выполняться как «вручную», так и при помощи функции
inet6_opt_set_val
. Наконец, мы должны вызвать
inet6_opt_finish
. Альтернативный вариант действий состоит в выделении буфера достаточно большого размера для нашего параметра. В этом случае первый проход можно не выполнять. Однако если изменение параметров приведет к переполнению выделенного буфера, в программе возникнет ошибка.
Оставшиеся три функции обрабатывают полученный параметр.
#include <netinet/in.h>
int inet6_opt_next(const void * extbuf, socklen_t extlen,
Возвращает:
смещение следующего параметра, -1 в случае достижения конца списка параметров или в случае ошибки
int inet6_opt_find(const void * extbuf, socklen_t extlen,
int offset, uint8_t type, socklen_t * lenp, void ** databufp);
Возвращает: смещение следующего параметра, -1 в случае достижения конца списка параметров или в случае ошибки
int inet6_opt_get_val(const void * databuf, int offset, void * val, socklen_t vallen);
Возвращает: новое значение смещения внутри буфера databuf
Функция
inet6_opt_next
обрабатывает следующий параметр в буфере. Аргументы
extbuf
и
extlen
определяют буфер, в котором содержится заголовок. Как и у
inet6_opt_append
, аргумент
offset
представляет собой текущее смещение внутри буфера. При первом вызове
inet6_opt_next
значение этого аргумента должно быть равно нулю, а при всех последующих — значению, возвращенному при предыдущем вызове функции. Аргументы
typep
,
lenp
и
databufp
предназначены для возвращения функцией типа, длины и значения параметра соответственно. Функция
inet6_opt_next
возвращает -1 в случае обработки заголовка с нарушенной структурой или в случае достижения конца буфера.
Функция
inet6_opt_find
аналогична предыдущей функции, но позволяет вызывающему процессу задать тип параметра, который следует искать (аргумент type), вместо того чтобы каждый раз возвращать следующий параметр.
Функция
inet6_opt_get_val
предназначена для извлечения значений из параметра по указателю
databuf
, возвращаемому предшествующим вызовом
inet6_opt_next
или
inet6_opt_find
. Как и для
inet6_opt_set_val
, аргумент
offset
должен начинаться с 0 для каждого параметра, а затем должен приравниваться значению, возвращаемому предшествующим вызовом
inet6_opt_get_val
.
27.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
. Но для получения заголовка маршрутизации требуется, чтобы был включен параметр