Литмир - Электронная Библиотека
Содержание  
A
A

27.8. История развития интерфейса IPv6

Документ RFC 2292 [113] определял более раннюю версию описываемого интерфейса, которая была реализована в некоторых системах. В этой версии для работы с параметрами получателя и транзитных узлов использовались функции

inet6_option_space
,
inet6_option_init
,
inet6_option_append
,
inet6_option_alloc
,
inet6_option_next
и
inet6_option_find
. Эти функции работали непосредственно с объектами типа
struct cmsghdr
, предполагая, что все параметры содержатся во вспомогательных данных. Для работы с заголовками маршрутизации были предназначены функции
inet6_rthdr_space
,
inet6_rthdr_init
,
inet6_rthdr_add
,
inet6_rthdr_lasthop
,
inet6_rthdr_reverse
,
inet6_rthdr_segments
,
inet6_rthdr_getaddr
и
inet6_rthdr_getflags
. Эти функции также работали непосредственно со вспомогательными данными.

В этом API закрепленные параметры устанавливались при помощи параметра сокета

IPV6_PKTOPTIONS
. Объекты вспомогательных данных при этом передавались в качестве данных параметра
IPV6_PKTOPTIONS
. Нынешние параметры сокета
IPV6_DSTOPTS
,
IPV6_HOPOPTS
и
IPV6_RTHDR
были флагами, позволявшими получать соответствующие заголовки во вспомогательных данных.

Подробнее обо всем этом вы можете прочесть в разделах 4–8 документа RFC 2292 [113].

27.9. Резюме

Из десяти определенных в IPv4 параметров наиболее часто используются параметры маршрутизации от отправителя, но в настоящее время их популярность падает из-за проблем, связанных с безопасностью. Доступ к параметрам заголовков IPv4 осуществляется с помощью параметра сокета

IP_OPTIONS
.

В IPv6 определены шесть заголовков расширения. Доступ к заголовкам расширения IPv6 осуществляется с помощью функционального интерфейса, что освобождает нас от необходимости углубляться в детали фактического формата пакета. Эти заголовки расширения записываются как вспомогательные данные функцией

sendmsg
и возвращаются функцией
recvmsg
также в виде вспомогательных данных.

Упражнения

1. Что изменится, если в нашем примере, приведенном в конце раздела 27.3, мы зададим каждый промежуточный узел с параметром

-G
вместо
-g
?

2. Размер буфера, указываемый в качестве аргумента функции

setsockopt
для параметра сокета
IP_OPTIONS
, должен быть кратен 4 байтам. Что бы нам пришлось делать, если бы мы не поместили параметр NOP в начало буфера, как показано на рис. 27.1?

3. Каким образом программа

ping
получает маршрут от отправителя, когда используется параметр IP Record Route (запись маршрута), описанный в разделе 7.3 [128]?

4. Почему в примере кода для сервера

rlogind
, приведенном в конце раздела 27.3, который предназначен для удаления полученного маршрута от отправителя, дескриптор сокета (первый аргумент функций
getsockopt
и
setsockopt
) имеет нулевое значение?

5. В течение долгого времени для удаления маршрута использовался код, несколько отличающийся от приведенного в конце раздела 27.3. Он выглядел следующим образом:

optsize = 0;

setsockopt(0, ipproto, IP_OPTIONS, NULL, &optsize);

Что в этом фрагменте неправильно? Имеет ли это значение?

Глава 28

Символьные сокеты

28.1. Введение

Символьные, или неструктурированные, сокеты (raw sockets) обеспечивают три возможности, не предоставляемые обычными сокетами TCP и UDP.

1. Символьные сокеты позволяют читать и записывать пакеты ICMPv4, IGMPv4 и ICMPv6. Например, программа

ping
посылает эхо-запросы ICMP и получает эхо-ответы ICMP. (Наша оригинальная версия программы
ping
приведена в разделе 28.5.) Демон маршрутизации многоадресной передачи
mrouted
посылает и получает пакеты IGMPv4.

2. Эта возможность также позволяет реализовывать как пользовательские процессы те приложения, которые построены с использованием протоколов ICMP и IGMP, вместо того чтобы помещать большее количество кода в ядро. Например, подобным образом построен демон обнаружения маршрутов (

in.rdisc
в системе Solaris 2.x. В приложении F книги [111] рассказывается, как можно получить исходный код открытой версии). Этот демон обрабатывает два типа сообщений ICMP, о которых ядро ничего не знает (извещение маршрутизатора и запрос маршрутизатору).

С помощью символьных сокетов процесс может читать и записывать IPv4-дейтаграммы с полем протокола IPv4, которое не обрабатывается ядром. Посмотрите еще раз на 8-разрядное поле протокола IPv4, изображенное на рис. А.1. Большинство ядер обрабатывают дейтаграммы, содержащие значения поля протокола 1 (ICMP), 2 (IGMP), 6 (TCP) и 17 (UDP). Но для этого поля определено гораздо большее количество значений, полный список которых приведен в реестре IANA «Номера протоколов» (Protocol Numbers). Например, протокол маршрутизации OSPF не использует протоколы TCP или UDP, а работает напрямую с протоколом IP, устанавливая в поле протокола значение 89 для IP-дейтаграмм. Программа

gated
, реализующая OSPF, должна использовать для чтения и записи таких IP-дейтаграмм символьный сокет, поскольку они содержат значение поля протокола, о котором ничего не известно ядру. Эта возможность также переносится в версию IPv6.

3. С помощью символьных сокетов процесс может построить собственный заголовок IPv4 при помощи параметра сокета

IP_HDRINCL
. Такую возможность имеет смысл использовать, например, для построения собственного пакета UDP или TCP. Подобный пример приведен в разделе 29.7.

В данной главе описывается создание символьных сокетов, а также операции ввода и вывода с этими сокетами. Далее приводятся версии программ

ping
и
traceroute
, работающие как с версией IPv4, так и с версией IPv6.

28.2. Создание символьных сокетов

При создании символьных сокетов выполняются следующие шаги:

1. Символьный сокет создается функцией

socket
со вторым аргументом
SOCK_RAW
. Третий аргумент (протокол) обычно ненулевой. Например, для создания символьного сокета IPv4 следует написать:

int sockfd;

sockfd = socket(AF_INET, SOCK_RAW, <i>protocol</i>);

306
{"b":"225366","o":1}