UNIX: разработка сетевых приложений — страница 35 из 42

Приложение АПротоколы IPv4, IPv6, ICMPv4 и ICMFV6

А.1. Введение

В этом приложении приведен обзор протоколов IPv4, IPv6, ICMPv4 и ICMPv6. Данный материал позволяет глубже понять рассмотренные в главе 2 протоколы TCP и UDP. Некоторые возможности IP и ICMP рассматриваются также более подробно и в других главах, например параметры IP (см. главу 27), и программы

ping
и
traceroute
(см. главу 28).

А.2. Заголовок IPv4

Уровень IP обеспечивает не ориентированную на установление соединения (connectionless) и ненадежную службу доставки дейтаграмм (RFC 791 [94]). Уровень IP делает все возможное для доставки IP-дейтаграммы определенному адресату, но не гарантирует, что дейтаграмма будет доставлена, прибудет в нужном порядке относительно других пакетов, а также будет доставлена в единственном экземпляре. Если требуется надежная доставка дейтаграммы, она должна быть обеспечена на более высоком уровне. В случае приложений TCP и SCTP надежность обеспечивается транспортным уровнем. Приложению UDP надежность должно обеспечивать само приложение, поскольку уровень UDP также не предоставляет гарантии надежной доставки дейтаграмм, что было показано на примере в разделе 22.5.

Одной из наиболее важных функций уровня IP является маршрутизация (routing). Каждая IP-дейтаграмма содержит адрес отправителя и адрес получателя. На рис. А.1 показан формат заголовка Ipv4.

Рис. А.1. Формат заголовка IPv4

■ Значение 4-разрядного поля версия (version) равно 4. Это версия протокола IP, используемая с начала 80-х.

■ В поле длина заголовка (header length) указывается полная длина IP-заголовка, включающая любые параметры, описанные 32-разрядными словами. Максимальное значение этого 4-разрядного поля равно 15, и это значение задает максимальную длину IP-заголовка 60 байт. Таким образом, если заголовок занимает фиксированные 20 байт, то 40 байт остается на различные параметры.

■ 16-разрядное поле кода дифференцированных сервисов (Differentiated Services Code Point, DSCP) (RFC 2474 [82]) и 2-разрядное поле явного уведомления о загруженности сети (Explicit Congestion Notification, ECN) (RFC 3168 [100]) заменили 8-разрядное поле тип службы (сервиса) (type-of-service, TOS), которое описывалось в RFC 1349 [5]. Все 8 разрядов этого поля можно установить с помощью параметра сокета IP_TOS (см. раздел 7.6), хотя ядро может перезаписать любое установленное нами значение при проведении политики Diffserv или реализации ECN.

■ Поле общая длина (total length) имеет размер 16 бит и задает полную длину IP- дейтаграммы в байтах, включая заголовок IPv4. Количество данных в дейтаграмме равно значению этого поля минус длина заголовка, умноженная на 4. Данное поле необходимо, поскольку некоторые каналы передачи данных заполняют кадр до некоторой минимальной длины (например, Ethernet) и возможна ситуация, когда размер действительной IP-дейтаграммы окажется меньше требуемого минимума.

■ 16-разрядное поле идентификации (identification) является уникальным для каждой IP-дейтаграммы и используется при фрагментации и последующей сборке в единое целое (см. раздел 2.11). Значение должно быть уникальным для каждого сочетания отправителя, получателя и протокола в течение того времени, пока дейтаграмма может находиться в пути. Если пакет ни при каких условиях не может подвергнуться фрагментации (например, установлен бит DF), нет необходимости устанавливать значение этого поля.

■ Бит DF (флаг запрета фрагментации), бит MF (указывающий, что есть еще фрагменты для обработки) и 13-разрядное поле смещения фрагмента (fragment offset) также используются при фрагментации и последующей сборке в единое целое. Бит DF полезен при обнаружении транспортной MTU (раздел 2.11).

■ 8-разрядное поле времени жизни (time-to-live, TTL) устанавливается отправителем и уменьшается на единицу каждым последующим маршрутизатором, через который проходит дейтаграмма. Дейтаграмма отбрасывается маршрутизатором, который уменьшает данное поле до нуля. При этом время жизни любой дейтаграммы ограничивается 255 пересылками. Обычно по умолчанию данное поле имеет значение 64, но можно сделать соответствующий запрос и изменить его с помощью параметров сокета

IP_TTL
и
IP_MULTICAST_TTL
(см. раздел 7.6).

■ 8-разрядное поле протокола (protocol) определяет тип данных, содержащихся в IP-дейтаграмме. Характерные значения этого поля — 1 (ICMPv4), 2 (IGMPv4), 6 (TCP) и 17 (UDP). Эти значения определены в реестре IANA «Номера протоколов».

■ 16-разрядная контрольная сумма заголовка (header checksum) вычисляется для IP-заголовка (включая параметры). В качестве алгоритма вычисления используется стандартный алгоритм контрольных сумм для Интернета — простое суммирование 16-разрядных обратных кодов, как показано в листинге 28.11.

■ Два поля — IPv4-адрес отправителя (source IPv4 address) и IPv4-адрес получателя (destination IPv4 address) — занимают по 32 бита.

■ Поле параметров (options) описывается в разделе 27.2, а пример IPv4-параметра маршрута от отправителя приведен в разделе 27.3.

А.3. Заголовок IPv6

На рис. А.2 показан формат заголовка IPv6 (RFC 2460 [27]).

Рис. А.2. Формат заголовка IPv6

■ Значение 4-разрядного поля номера версии (version) равно 6. Данное поле занимает первые 4 бита первого байта заголовка (так же как и в версии IPv4, см. рис. А.1), поэтому если получающий стек IP поддерживает обе версии, он имеет возможность определить, какая из версий используется.

Когда в начале 90-х развивался протокол IPv6 и еще не был принят номер версии 6, протокол назывался IPng (IP next generation — IP нового поколения). До сих пор можно встретить ссылки на IPng.

■ 6-разрядное поле кода дифференцированных сервисов (Differentiated Services Code Point, DSCP) (RFC 2474 [82]) и 2-разрядное поле явного уведомления о загруженности сети (Explicit Congestion Notification, ECN) (RFC 3168 [100]) заменили 8-разрядное поле класса трафика, которое описывалось RFC 2460. Все 8 бит этого поля можно установить при помощи параметра сокета IPV6_TCLASS (раздел 22.8), но ядро может перезаписать установленное нами значение, выполняя политику Diffserv или реализуя ECN.

■ Поле метки потока (flow label) занимает 20 разрядов и может заполняться приложением для данного сокета. Поток представляет собой последовательность пакетов от конкретного отправителя определенному получателю, для которых отправитель потребовал специальную обработку промежуточными маршрутизаторами. Если для данного потока отправитель назначил метку, она уже не изменяется. Метка потока, равная нулю (по умолчанию), обозначает пакеты, не принадлежащие потоку. Метка потока не меняется при передаче по сети. Подробное описание использования меток потока приводится в [99]. Интерфейс метки потока еще не определен до конца. Поле

sin6_flowinfo
структуры адреса сокета
sockaddr_in6
(см. листинг 3.3) зарезервировано для будущего использования. Некоторые системы копируют младшие 28 разрядов
sin6_flowinfo
непосредственно в заголовок пакета IPv6, перезаписывая поля DSCP и ECN.

■ Поле длины данных (payload length) занимает 16 бит и содержит длину данных в байтах, которые следуют за 40 байтами IPv6-заголовка. Нулевое значение этого поля указывает, что длина требует больше 16 бит и содержится в параметре размера увеличенного поля данных (jumbo payload length option) (см. рис. 27.5). Данные с увеличенной таким образом длиной называются джумбограммой (jumbogram).

■ Следующее поле содержит 8 бит и называется полем следующего заголовка (next header). Оно аналогично полю протокола (protocol) IPv4. Действительно, когда верхний уровень в основном не меняется, используются те же значения, например, 6 для TCP и 17 для UDP. Но при переходе от ICMPv4 к ICMPv6 возникло так много изменений, что для последнего было принято новое значение 58. Дейтаграмма IPv6 может иметь множество заголовков, следующих за 40-байтовым заголовком IPv6. Поэтому поле и называется «полем следующего заголовка», а не полем протокола.

■ Поле ограничения пересылок или предельного количества транзитных узлов (hop limit) аналогично полю TTL IPv4. Значение этого поля уменьшается на единицу каждым маршрутизатором, через который проходит дейтаграмма, и дейтаграмма отбрасывается тем маршрутизатором, который уменьшает данное поле до нуля. Значение этого поля можно установить и получить с помощью параметров сокета

IPV6_UNICAST_HOPS
и
IPV6_MULTICAST_HOPS
(см. раздел 7.8 и 21.6). Параметр сокета
IPV6_HOPLIMIT
также позволяет установить это поле, а параметр
IPV6_RECVHOPLIMIT
 — узнать его значение для полученной дейтаграммы.

ПРИМЕЧАНИЕ

В ранних спецификациях IPv4 говорилось, что маршрутизаторы должны уменьшать значение TTL либо на единицу, либо на количество секунд, в течение которых дейтаграмма находилась на маршрутизаторе, если это количество превышает единицу. Поэтому поле и называлось «время жизни». Однако на практике TTL всегда уменьшалось на единицу. IPv6 разрешает уменьшать поле количества транзитных узлов только на единицу, поэтому и название поля было изменено.

■ Два следующих поля IPv6-адрес отправителя (source IPv6 address) и IPv6-адрес получателя (destination IPv6 address) занимают по 128 бит.

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

■ В IPv6 нет поля длины заголовка, поскольку в заголовке отсутствуют параметры. Существует возможность использовать после фиксированного 40-байтового заголовка дополнительные заголовки, но каждый из них имеет свое поле длины.

■ Два адреса IPv6 выровнены по 64-разрядной границе, если заголовок также является 64-разрядным. Такой подход может увеличить скорость обработки на 64-разрядных архитектурах. Адреса IPv4 имеют 32-разрядное выравнивание в заголовке IPv4, который в целом выровнен по 64 разрядам.

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

■ Заголовок IPv6 не включает в себя свою контрольную сумму. Такое изменение было сделано, поскольку все верхние уровни — TCP, UDP и ICMPv6 — имеют свои контрольные суммы, включающие в себя заголовок верхнего уровня, данные верхнего уровня и такие поля из IPv6-заголовка, как IPv6-адрес отправителя, IPv6-адрес получателя, длину данных и следующий заголовок. Исключив контрольную сумму из заголовка, мы приходим к тому, что маршрутизатор, перенаправляющий пакет, не должен будет пересчитывать контрольную сумму заголовка после того, как изменит поле ограничения пересылок. Ключевым моментом здесь также является скорость маршрутизации.

Если это ваше первое знакомство с IPv6, также следует отметить главные отличия IPv6 от IPv4:

■ В IPv6 отсутствует многоадресная передача (см. главу 20). Групповая адресация (см. главу 21), не являющаяся обязательной для IPv4, требуется для IPv6.

■ В IPv6 маршрутизаторы не фрагментируют перенаправляемые пакеты. Если пакет слишком велик, маршрутизатор сбрасывает его и отправляет сообщение об ошибке ICMPv6 (раздел А.6). Фрагментация при использовании IPv6 осуществляется только узлом отправителя.

■ IPv6 требует поддержки обнаружения транспортной MTU (раздел 2.11). Технически эта поддержка не является обязательной и может не включаться в реализации, обладающие минимальной функциональностью, такие как сетевые загрузчики, но если узел не обнаруживает транспортную MTU, он не должен отсылать дейтаграммы, размер которых превышает минимальную канальную MTU IPv6 (1280 байт). В разделе 22.9 описываются параметры сокетов, управляющие поведением механизма обнаружения транспортной MTU.

■ IPv6 требует поддержки параметра аутентификации (подтверждения прав доступа) и параметра обеспечения безопасности. Эти параметры добавляются после основного заголовка.

А.4. Адресация IPv4

Адреса IPv4 состоят из 32 разрядов и обычно записываются в виде последовательности из четырех чисел в десятичной форме, разделенных точками. Такая запись называется точечно-десятичной. Первое из четырех чисел определяет тип адреса (табл. А.1). Исторически IP-адреса делились на пять классов. Три класса направленных адресов эквивалентны друг другу с функциональной точки зрения, поэтому мы показываем их как один диапазон.


Таблица А.1. Диапазоны и классы IP-адресов

НазначениеКлассДиапазон
Направленная передачаА, В, С0.0.0.0–223.255.255.255
Многоадресная передачаD224.0.0.0–239.255.255.255
ЭкспериментальныеЕ240.0.0.0–255.255.255.255

Под сетевым адресом IPv4 подразумевается 32-разрядный адрес и соответствующая ему 32-разрядная маска подсети. Биты маски, равные 1, указывают адрес сети, а нулевые биты — адрес узла. Поскольку биты со значением 1 всегда занимают места в маске непрерывно начиная с крайнего левого бита, а нулевые биты — начиная с крайнего правого бита, то маску адреса можно определить как префиксную длину (prefix length), указывающую на количество заполненных единицами битов начиная с крайнего левого бита. Например, маска 255.255.255.0 соответствует префиксной длине 24. Такая адресация называется бесклассовой (classless), потому что маска указывается явно, а не задается классом адреса. Пример вы можете увидеть на рис. 1.7.

ПРИМЕЧАНИЕ

Маски подсети, не являющиеся непрерывными, не были явно запрещены ни в одном RFC, но такие маски усложняют работу администраторов и не могут быть представлены в префиксной записи. Протокол междоменной маршрутизации Интернета BGP4 может работать только с непрерывными масками. В протоколе IPv6 требование непрерывности маски выдвигается явно.

Использование бесклассовых адресов подразумевает бесклассовую маршрутизацию, которую обычно называют бесклассовой междоменной маршрутизацией (classless interdomain routing — CIDR) (RFC 1519 [31]). Бесклассовая междоменная маршрутизация позволяет сократить размер таблиц маршрутизации опорной сети Интернета и снизить скорость расходования адресов IPv4. Все маршруты CIDR характеризуются маской или длиной префикса. Маска больше не может быть определена по классу адреса. Более подробно CIDR описывается в разделе 10.8 книги [111].

Адреса подсетей

Обычно IPv4-адреса разделяются на подсети (RFC 950 [79]). Такой подход добавляет еще один уровень иерархии адресов:

■ идентификатор сети (присваивается предприятию);

■ идентификатор подсети (выбирается предприятием);

■ идентификатор узла (выбирается предприятием).

Граница между идентификатором сети и идентификатором подсети фиксирована префиксной длиной присвоенного адреса сети. Эта префиксная длина присваивается организациям их интернет-провайдером. Граница же между идентификатором подсети и идентификатором узла выбирается предприятием. Все узлы данной подсети имеют одинаковую маску подсети, которая и определяет границу между идентификатором подсети и идентификатором узла. Биты, заполненные единицами в маске подсети, соответствуют идентификатору подсети, а биты, заполненные нулями — идентификатору узла.

В качестве примера рассмотрим предприятие, которому был выделен адрес 192.168.42.0/24. Если это предприятие будет использовать 3-разрядный идентификатор подсети, на идентификатор узла останется 5 разрядов (рис. А.3.)

Рис. А.3. 24-разрядный адрес сети с 3-разрядным адресом подсети и 5-разрядным адресом узла

В результате такого деления мы получаем подсети, показанные в табл. А.2.


Таблица А.2. Список подсетей для 3-разрядного адреса подсети и 5-разрядного адреса узла

ПодсетьПрефикс
0192.168.42.0/27+
1192.168.42.32/27+
2192.168.42.64/27
3192.168.42.96/27
4192.168.42.128/27
5192.168.42.160/27
6192.168.42.192/27
7192.168.42.224/27+

В результате мы получаем 6–8 подсетей (идентификаторы 1–6 или 0–7), в каждой из которых может находиться до 30 узлов (идентификаторы 1–30). RFC 950 не рекомендует использовать подсети, идентификаторы которых состоят из одних нулей и одних единиц (знак «+» в табл. А.2). В настоящее время большинство систем поддерживают и такие адреса подсетей. Максимальный идентификатор узла (в нашем случае 31) зарезервирован за широковещательным адресом. Идентификатор 0 используется для адресации сети в целом и зарезервирован во избежание конфликтов со старыми системами, в которых нулевой адрес узла использовался в качестве адреса широковещательной передачи. В полностью контролируемых сетях, где такие системы отсутствуют, идентификатор 0 использовать можно. Вообще говоря, сетевые приложения не должны заботиться об идентификаторах подсетей и узлов, рассматривая IP-адреса как непрозрачные объекты.

Адрес закольцовки

По соглашению адрес 127.0.0.1 присвоен интерфейсу закольцовки на себя (loopback interface). Все, что посылается на этот IP-адрес, получается самим узлом. Обычно этот адрес используется при тестировании клиента и сервера на одном узле. Этот адрес известен под именем

INADDR_LOOPBACK
.

ПРИМЕЧАНИЕ

Любой адрес из подсети 127/8 можно присвоить интерфейсу закольцовки, но обычно используется именно 127.0.0.1.

Неопределенный адрес

Адрес, состоящий из 32 нулевых битов, является в IPv4 неопределенным (unspecified) адресом. В пакете IPv4 он может появиться только как адрес получателя в тех пакетах, которые посланы узлом, находящимся в состоянии загрузки, когда узел еще не знает своего IP-адреса. В API сокетов этот адрес называется универсальным адресом (wildcard address) и обычно обозначается

INADDR_ANY
. Указание этого адреса при вызове
bind
для прослушиваемого сокета TCP говорит о том, что сокет будет принимать входящие соединения на любой адрес данного узла.

Частные адреса

RFC 1918 [101] выделяет три диапазона адресов для «частных интрасетей», то есть сетей, не имеющих прямого подключения к Интернету. Эти диапазоны представлены в табл. А.3.


Таблица А.3. Диапазоны частных IP-адресов

Количество адресовПрефиксДиапазон
1677721610/810.0.0.0–10.255.255.255
1 048 576172.16/12172.16.0.0–172.31.255.255
65 536192.168/16192.168.0.0–192.168.255.255

Пакеты с этими адресами никогда не должны появляться в Интернете, они зарезервированы для использования в частных сетях. Многие небольшие предприятия используют эти адреса и осуществляют трансляцию сетевых адресов в единственный общий IP-адрес, видимый из Интернета.

Многоинтерфейсность и псевдонимы адресов

Традиционно многоинтерфейсный узел определяется как узел с несколькими интерфейсами, например узел, имеющий два интерфейса Ethernet или интерфейсы Ethernet и PPP. Каждый из интерфейсов должен иметь свой уникальный IPv4-адрес. При подсчете интерфейсов (для определения, является ли узел многоинтерфейсным) интерфейс закольцовки не учитывается.

Маршрутизатор по определению является многоинтерфейсным, поскольку он пересылает пакеты, поступившие на один интерфейс, через другой интерфейс. Но обратное неверно, то есть многоинтерфейсный узел не является маршрутизатором, если он не передает пакеты. Действительно, многоинтерфейсный узел еще не может рассматриваться как маршрутизатор. Он будет функционировать как маршрутизатор, только если он сконфигурирован для такой работы (обычно администратор должен включить соответствующие параметры конфигурации).

Термин «многоинтерфейсность» является более общим и охватывает два различных сценария (раздел 3.3.4 RFC 1122 [10]).

1. Узел с несколькими интерфейсами является многоинтерфейсным, при этом каждый интерфейс должен иметь свой IP-адрес. Это традиционное определение.

2. Современные узлы имеют возможность присваивать одному физическому интерфейсу несколько IP-адресов. Каждый IP-адрес, созданный в дополнение к первичному, или основному (primary), называется альтернативным именем, псевдонимом (alias) или логическим интерфейсом. Часто альтернативные IP-адреса используют ту же маску подсети, что и основной адрес, но имеют другие идентификаторы узла. Но допустима также ситуация, когда псевдонимы имеют адрес сети или подсети, совершенно отличный от первичного адреса. В разделе 17.6 приведен пример альтернативных адресов.

Таким образом, многоинтерфейсные узлы — это узлы, имеющие несколько интерфейсов IP-уровня, независимо от того, являются ли эти интерфейсы физическими или логическими.

ПРИМЕЧАНИЕ

Довольно часто загруженные серверы имеют несколько соединений с одним коммутатором Ethernet, причем эти соединения настраиваются как одно логическое соединение с повышенной пропускной способностью. Такая система имеет несколько физических интерфейсов, но не считается многоинтерфейсной, поскольку обладает одним-единственным логическим интерфейсом с точки зрения уровня IP.

ПРИМЕЧАНИЕ

Многоинтерфейсность также используется в другом контексте. Сеть, имеющая несколько соединений с сетью Интернет, также называется многоинтерфейсной. Например, некоторые сайты имеют два соединения с Интернетом вместо одного, что обеспечивает дублирование на случай неполадок. Транспортный протокол SCTP позволяет передавать информацию о количестве интерфейсов узла его собеседнику.

А.5. Адресация IPv6

Адреса IPv6 содержат 128 бит и обычно записываются как восемь 16-разрядных шестнадцатеричных чисел. Старшие биты 128-разрядного адреса обозначают тип адреса (RFC 3513 [44]). В табл. А.4 приведены различные значения старших битов и соответствующие им типы адресов.


Таблица А.4. Значение старших битов адреса IPv6

ЗначениеРазмер идентификатораПрефикс форматаДокумент
Не определеннет0000 0000 … 0000 0000 (128 разрядов)RFC 3513
Закольцовканет0000 0000 … 0000 0001 (128 разрядов)RFC 3513
Глобальный адрес направленной передачипроизвольный000RFC 3513
Глобальный адрес NSAPпроизвольный0000001RFC 1888
Объединяемый глобальный адрес направленной передачи64 разряда001RFC 3587
Глобальный адрес направленной передачи64 разрядавсе остальноеRFC 3513
Локальный в пределах канала адрес направленной передачи64 разряда1111 111010RFC 3513
Локальный в пределах сайта адрес направленной передачи64 разряда1111 111011RFC 3513
Групповой адреснет1111 1111RFC 3513

Эти старшие биты называются форматным префиксом. Например, если 3 старших бита — 001, адрес называется объединяемым глобальным индивидуальным адресом (aggregatable global unicast address). Если 8 старших битов —

11111111
(
0xff
), это групповой адрес.

Объединяемые глобальные индивидуальные адреса

Архитектура IPv6 корректировалась в процессе своего развития исходя из результатов внедрения новой версии протокола и из статистики применения старой версии. Согласно изначальному определению объединяемых глобальных индивидуальных адресов, они начинались с префикса 001 и имели фиксированную структуру, встроенную в сам адрес. Эта структура, однако, была отменена RFC 3587 [45]. Адреса, начинающиеся с префикса 001, будут и впредь выделяться в первую очередь, однако никаких отличий между ними и другими глобальными адресами больше не будет. Эти адреса будут использоваться в тех областях, где сейчас используются направленные адреса IPv4.

Формат объединяемых индивидуальных адресов определяется в RFC 3513 [44] и RFC 3587 [45] и содержит следующие поля, слева направо:

■ глобальный префикс маршрутизации (n разрядов);

■ идентификатор подсети (64 - n разрядов);

■ идентификатор интерфейса (64 разряда).

На рис. А.4 приведен пример объединяемого глобального индивидуального адреса.

Рис. А.4. Объединяемый глобальный индивидуальный адрес IPv6

Идентификатор интерфейса должен быть построен в модифицированном формате EUI-64 (Extended User Interface — расширенный интерфейс пользователя) [51]. Это расширение множества 48-разрядных адресов IEEE 802 MAC (Media Access Control — уровень управления доступом к среде передачи), которые присвоены большинству карт сетевых интерфейсов локальной сети. Этот идентификатор должен автоматически присваиваться интерфейсу и по возможности основываться на MAC-адресе карты. Более подробное описание построения идентификаторов интерфейса, основанных на EUI-64, описывается в приложении А RFC 3513 [44].

Поскольку модифицированный адрес EUI-64 может быть глобально уникальным идентификатором интерфейса, а сам интерфейс может однозначно идентифицировать пользователя, модифицированный формат EUI-64 создает определенные проблемы, связанные с конфиденциальностью. Может оказаться возможным отслеживать действия и перемещение конкретного пользователя, например путешествующего с портативным компьютером, просто по его IPv6-адресу. RFC 3041 [80] описывает расширения протокола, предназначенные для генерации идентификаторов интерфейса, меняющихся по несколько раз в день и, таким образом, устраняющие описанную проблему.

Тестовые адреса 6bone

6bone — это виртуальная сеть, используемая для тестирования протоколов IPv6 (см. раздел Б.3). Объединяемые глобальные индивидуальные адреса уже назначаются, но сайты, не имеющие права на адресное пространство согласно региональной политике назначения адресов, могут использовать адреса специального формата в сети 6bone RFC 2471 [46] (рис. А.5).

Рис. А.5. Тестовые адреса IPv6 для сети 6bone

Эти адреса рассматриваются как временные, и узлы, использующие такие адреса, необходимо будет перенумеровать, когда будут назначены объединяемые глобальные индивидуальные адреса.

Старшие три байта имеют значение 0x3ffe. Идентификатор сайта 6bone назначается председателем руководства 6bone. Назначение проводится в том же порядке, в котором оно будет проводиться для реальных адресов IPv6. Активность 6bone постепенно сворачивается по мере того, как начинается внедрение IPv6 (в 2002 году было выделено больше реальных адресов IPv6, чем во всей сети 6bone за 8 лет). Идентификаторы подсети и интерфейса используются, как и раньше, для обозначения подсети и узла.

В разделе 11.2 был показан IPv6-адрес 3ffe:b80:1f8d:1:a00:20ff:fea7:686b для узла

freebsd
(см. рис. 1.7). Идентификатор 6bone имеет значение 0x0b801f8d, а идентификатор подсети 0x1. Младшие 64 разряда представляют собой модифицированный адрес EUI-64, полученный из MAC-адреса Ethernet-карты узла.

Адреса IPv4, преобразованные к виду IPv6

Адреса IPv4, преобразованные к виду IPv6 (IPv4-mapped IPv6 addresses), позволяют приложениям, запущенным на узлах, поддерживающих как IPv4, так и IPv6, связываться с узлами, поддерживающими только IPv4, в процессе перехода сети Интернет на версию протокола IPv6. Такие адреса автоматически создаются на серверах DNS (см. табл. 11.3), когда приложением IPv6 запрашивается IPv6-адрес узла, который имеет только адреса IPv4.

Рисунок 12.3 показывает, что использование данного типа адресов с сокетом IPv6 приводит к отправке IPv4-дейтаграммы узлу. Такие адреса не хранятся ни в каких файлах данных DNS — при необходимости они создаются сервером.

Рис. А.6. Адреса IPv4, преобразованные к виду IPv6

На рис. А.6 приведен формат таких адресов. Младшие 32 бита содержат адрес IPv4.

При записи IPv6-адреса последовательная строка из нулей может быть сокращена до двух двоеточий. Вложенный IPv4-адрес представлен в точечно-десятичной записи. Например, преобразованный к виду IPv6 IPv4-адрес 0:0:0:0:0:FFFF:206.62.226.33 можно сократить до ::FFFF:206.62.226.33.

Адреса IPv6, совместимые с IPv4

Для перехода от версии IPv4 к IPv6 планировалось также использовать адреса IPv6, совместимые с IPv4 (IPv4-compatible IPv6 addresses). Администратор узла, поддерживающего как IPv4, так и IPv6, и не имеющего соседнего IPv6-маршрутизатора, должен создать DNS запись типа AAAA, содержащую адрес IPv6, совместимый с IPv4. Любой другой IPv6-узел, посылающий IPv6-дейтаграмму на адрес IPv6, совместимый с IPv4, должен упаковать (encapsulate) IPv6-дейтаграмму в заголовок IPv4 — такой способ называется автоматическим туннелированием (automatic tunnel). Однако после рассмотрения вопросов, связанных с внедрением IPv6, использование этой возможности заметно сократилось. Более подробно вопросы туннелирования будут рассмотрены в разделе Б.3, а на рис. Б.2 будет приведен пример IPv6-дейтаграмм такого типа, упакованных в заголовок IPv4.

На рис. А.7 показан формат адреса IPv4, совместимого с IPv6.

Рис. А.7. Адрес IPv6, совместимый с IPv4

В качестве примера такого адреса можно привести ::206.62.226.33.

Адреса IPv6, совместимые с IPv4 могут появляться и в пакетах IPv6, не передающихся по туннелю, если используется механизм перехода SIIT IPv4/IPv6 (RFC 2765 [83]).

Адрес закольцовки

Адрес IPv6 ::1, состоящий из 127 нулевых битов и единственного единичного бита, является адресом закольцовки IPv6. В API сокетов он называется

in6addr_loopback
или
IN6ADDR_LOOPBACK_INIТ
.

Неопределенный адрес

Адрес IPv6, состоящий из 128 нулевых битов, записываемый как 0::0 или просто ::, является неопределенным адресом IPv6 (unspecified address). В пакете IPv6 он может появиться только как адрес получателя в пакетах, посланных узлом, который находится в состоянии загрузки и еще не знает своего IPv6-адреса.

В API сокетов этот адрес называется универсальным адресом, и его использование, например, в функции

bind
для связывания прослушиваемого сокета TCP означает, что сокет будет принимать клиентские соединения, предназначенные любому из адресов узла. Этот адрес имеет имя
in6addr_any
или
IN6ADDR_ANY_INIT
.

Адрес локальной связи

Адрес локальной связи (link-local, локальный в пределах физической подсети) используется для соединения в пределах одной физической подсети, когда известно, что дейтаграмма не будет перенаправляться. Примерами использования таких адресов являются автоматическая конфигурация адреса во время загрузки и поиска соседних узлов (neighbor discovery) (подобно ARP для IPv4). На рис. А.8 приведен формат такого адреса.

Рис. А.8. IPv6-адрес локальной связи

Такие адреса всегда начинаются с

fe80
. Маршрутизатор IPv6 не должен перенаправлять дейтаграммы, у которых в поле отправителя или получателя указан адрес локальной связи, по другому соединению. В разделе 11.2 приведен адрес локальной связи, связанный с именем
aiх-611
.

Адрес, локальный на уровне сайта

На момент написания этой книги рабочей группой IETF по IPv6 было принято решение отменить локальные в пределах сайта адреса в их текущей форме. В тех адресах, которые придут им на замену, может использоваться тот же диапазон, который был отведен для локальных на уровне сайта адресов изначально (fec0/10).

Адрес, локальный в пределах сайта, должен был использоваться для адресации внутри предприятия, когда не требуется глобальный префикс. На рис. А.9 показан формат таких адресов.

Рис. А.9. IPv6-адрес, локальный в пределах сайта

Маршрутизатор IPv6 не должен перенаправлять дейтаграммы, для которых в поле отправителя или получателя указан такой адрес, за пределы предприятия.

А.6. ICMPv4 и ICMPv6: протоколы управляющих сообщений в сети Интернет

Протокол ICMP (Internet Control Message Protocol) является необходимой и неотъемлемой частью любой реализации IPv4 или IPv6. Протокол ICMP обычно используется для обмена сообщениями об ошибках между узлами, как маршрутизирующими, так и обычными, но иногда этот протокол используется и приложениями. Например, приложения

ping
и
traceroute
(см. главу 28) используют протокол ICMP.

Первые 32 бита сообщений совпадают для ICMPv4 и ICMPv6 и приведены на рис. А.10. ICMPv4 документируется в RFC 792 [95], а ICMPv6 — в RFC 2463 [21].

Рис. А.10. Формат сообщений ICMPv4 и ICMPv6

Восьмиразрядное поле тип (type) указывает тип сообщения ICMPv4 или ICMPv6, а некоторые типы имеют дополнительную 8-разрядную информацию, указанную в поле кода (code). Поле контрольной суммы (checksum) является стандартной контрольной суммой, используемой в сети Интернет. Отличия между ICMPv4 и ICMPv6 заключаются в том, какие именно поля используются при подсчете контрольной суммы.

С точки зрения сетевого программирования необходимо понимать, какие сообщения ICMP могут быть возвращены приложению, что именно вызывает ошибку и каким образом эта ошибка возвращается приложению. В табл. А.5 приведены все сообщения ICMPv4 и показано, как они обрабатываются операционной системой 4.4BSD. В последнем столбце приведены значения переменной

errno
— то есть те ошибки, которые возвращаются приложениям. В табл. А.6 приведен список сообщений ICMPv6. При использовании TCP ошибка не возвращается приложению немедленно. Если TCP разрывает соединение по тайм-ауту, все накопленные ошибки возвращаются приложению. При использовании UDP ошибка возвращается при очередной операции чтения или записи, но только на присоединенном сокете (раздел 8.9).


Таблица А.5. Обработка различных типов ICMP-сообщений в 4.4BSD

ТипКодОписаниеОбработчик или errno
00Echo-reply (Эхо-ответ)Пользовательский процесс (Ping)
3Destination unreachable (Получатель недоступен)
0Network unreachable (Сеть недоступна)EHOSTUNREACH
1Host unreachable (Узел недоступен)EHOSTUNREACH
2Protocol unreachable (Протокол недоступен)ECONNREFUSED
3Port unreachable (Порт недоступен)ECONNREFUSED
4Fragmentation needed but DF bit set (Необходима фрагментация, но установлен бит DF)EMSGSIZE
5Source route failed (Сбой маршрута отправителя)EHOSTUNREACH
6Destination network unknown (Неизвестна сеть получателя)EHOSTUNREACH
7Destination host unknown (Неизвестен узел получателя)EHOSTUNREACH
8Source host isolated (Узел отправителя изолирован). Устаревший тип сообщенийEHOSTUNREACH
9Destination network administratively prohibited (Сеть получателя запрещена администратором)EHOSTUNREACH
10Destination host administratively prohibited (Узел получателя запрещен администратором)EHOSTUNREACH
11Network unreachable for TOS (Сеть недоступна для TOS)EHOSTUNREACH
12Host unreachable for TOS (Узел недоступен для TOS)EHOSTUNREACH
13Communication administratively prohibited (Связь запрещена администратором)(Игнорируется)
14Host precedence violation (Нарушение порядка старшинства узлов)(Игнорируется)
15Precedence cutoff in effect (Действует старшинство узлов)(Игнорируется)
40Source quench (Отключение отправителя)Обрабатывается ядром в случае TCP, игнорируется в случае UDP
5Redirect (Перенаправление)
0Redirect for network (Перенаправление для сети)Ядро обновляет таблицу маршрутизации
1Redirect for host (Перенаправление для узла)Ядро обновляет таблицу маршрутизации
2Redirect for type-of-service and network (Перенаправление для типа сервиса и сети)Ядро обновляет таблицу маршрутизации
3Redirect for type of service and host (Перенаправление для типа сервиса и узла)Ядро обновляет таблицу маршрутизации
80Echo request (Эхо-запрос)Ядро генерирует ответ
90Router advertisement (Извещение маршрутизатора)Пользовательский процесс
100Router solicitation (Запрос маршрутизатору)Пользовательский процесс
11Time exceeded (Превышено время передачи)
0TTL equals 0 during transit (Время жизни равно 0 во время передачи)Пользовательский процесс
1TTL equals 0 during reassembly (Время жизни равно 0 во время сборки)Пользовательский процесс
12Parameter problem (Проблема с параметром)
0IP header bad (Неправильный IP-заголовок). Типичная ошибкаENOPROTOOPT
1Required option missed (Пропущен необходимый параметр)ENOPROTOOPT
130Timestamp request (Запрос отметки времени)Ядро генерирует ответ
140Timestamp reply (Ответ об отметке времени)Пользовательский процесс
150Information request (Информационный запрос). Устаревший тип сообщений(игнорируется)
160Information reply (Информационный ответ). Устаревший тип сообщенийПользовательский процесс
170Address mask request (Запрос маски адреса)Ядро генерирует ответ
180Address mask reply (Ответ маски адреса)Пользовательский процесс

Таблица А.6. Сообщения ICMPv6

ТипКодОписаниеОбработчик или errno
1Administratively prohibited, firewall filter (Запрещено администратором, фильтр брандмауэра)EHOSTUNREACH
2Not a neighbor, incorrect strict source route (He сосед, некорректный маршрут отправителя)EHOSTUNREACH
3Address unreachable (Адрес недоступен)EHOSTDOWN
4Port unreachable (Порт недоступен)ECONNREFUSED
20Packet too big (Слишком большой пакет)Ядро выполняет обнаружение транспортной MTU
3Time exceeded (Превышено время передачи)
0Hop limit exceeded in transit (При передаче превышено значение предельного количества транзитных узлов)Пользовательский процесс
1Fragment reassembly time exceeded (Истекло время сборки из фрагментов)Пользовательский процесс
4Parameter problem (Проблема с параметром)
0Erroneous header filed (Ошибочное поле заголовка)ENOPROTOOPT
1Unrecognized next header (Следующий заголовок нераспознаваем)ENOPROTOOPT
2Unrecognized option (Неизвестный параметр)ENOPROTOOPT
1280Echo request (Эхо-запрос (Ping))Ядро генерирует ответ
1290Echo reply (Эхо-ответ (Ping))Пользовательский процесс (Ping)
1300Group membership query (Запрос о членстве в группе)Пользовательский процесс
1310Group membership report (Отчет о членстве в группе)Пользовательский процесс
1320Group membership reduction (Сокращение членства в группе)Пользовательский процесс
1330Router solicitation (Запрос маршрутизатору)Пользовательский процесс
1340Router advertisement (Извещение маршрутизатора)Пользовательский процесс
1350Neighbor solicitation (Запрос соседу)Пользовательский процесс
1360Neighbor advertisement (Извещение соседа)Пользовательский процесс
1370Redirect (Перенаправление)Ядро обновляет таблицу маршрутизации

Запись «пользовательский процесс» в этой таблице означает, что ядро не обрабатывает сообщение и ждет обработки данного сообщения от пользовательского процесса с символьным сокетом. Также следует отметить, что различные реализации могут обрабатывать одни и те же сообщения по-разному. Например, в Unix сообщения типа

Router solicitation
(Запрос маршрутизатору) и
Router advertisement
(Извещение маршрутизатора) обычно обрабатываются как пользовательские процессы, но некоторые реализации могут обрабатывать эти сообщения в ядре.

Версия ICMPv6 сбрасывает старший бит поля тип для сообщения об ошибке (типы 1-4) и устанавливает этот бит для информационного сообщения (типы 128–137).

Приложение Б