Семейство интернет-протоколов версии 6
#include <netinet/in.h>struct sockaddr_in6 {uint8_t sin6_len;sa_family_t sin6_family;in_port_t sin6_port;uint32_t sin6_flowinfo;struct in6_addr sin6_addr;uint32_t sin6_scope_id;};
Протоколы
Семейство INET6 состоит из следующих протоколов:
TCP поддерживает абстракцию SOCK_STREAM
, а UDP поддерживает абстракцию SOCK_DGRAM
. Обратите внимание, что TCP и UDP являются общими для INET и INET6. Сырой интерфейс для IPv6 доступен путем создания сокета Internet SOCK_RAW
. Доступ к протоколу сообщений ICMPv6 можно получить из сырого сокета.
Семейство протоколов INET6 - это обновленная версия семейства INET. В то время как INET реализует Интернет-протокол версии 4, INET6 реализует Интернет-протокол версии 6.
Адресация
Адреса IPv6 представляют собой 16-байтовые
значения, хранящиеся в стандартном сетевом порядке байт (прямом порядком байт). Заголовочный файл <netinet/in.h>
определяет эти адреса как объединение (union).
Сокеты, связанные с семейством INET6, используют структуру, описанную выше.
Можно создавать сокеты с локальным адресом :: (что эквивалентно IPv6 адресу 0:0:0:0:0:0:0:0
) чтобы использовать как бы подстановку “специальных символов” на входящие сообщения. Можно задать адрес при вызове connect() или sendto() в виде :: чтобы обозначить тем самым локальный хост. Можно получить значение :: путем установки поля sin6_addr в значение 0
, либо путем использования адреса, хранящегося в глобальной переменной in6addr_any, объявленной в <netinet6/in6.h>
.
Спецификация IPv6 определяет addresses с ограниченной областью действия, такой как link-local или site-local. Адрес с заданной областью неоднозначен для ядра, если он указан без идентификатора области. Чтобы правильно управлять адресами с заданной областью действия в приложении, следует использовать расширенное API, определенное в RFC 2292. Краткое описание расширенного API доступно в IP6. При указании адреса с заданной областью без явной области, диспетчер сокетов может вернуть ошибку.
![]() | Адреса с заданной областью в настоящее время являются экспериментальными как с точки зрения спецификации, так и с точки зрения реализации. |
Реализация KAME поддерживает расширенную числовую нотацию IPv6-адресов для локальных адресов. Например, можно использовать fe80::1%de0 для указания “fe80::1 на интерфейсе de0.” Функции getaddrinfo() и getnameinfo() поддерживают такую нотацию. Некоторые утилиты, такие как telnet и ftp, также могут использовать подобную нотацию. С использованием специальных программ, таких как ping6, можно устранить неоднозначность адресов с заданной областью, указав исходящий интерфейс с дополнительными параметрами командной строки.
Менеджер сокетов особым образом обрабатывает адреса с заданной областью действия. В таблицах маршрутизации или структурах интерфейса менеджера сокетов индекс интерфейса адреса с заданной областью встроен в адрес. Следовательно, адрес, содержащийся в некоторых структурах менеджера сокетов, не совпадает с адресом в сети. Встроенный индекс становится видимым при использовании сокета PF_ROUTE
или функции sysctl(). Не рекомендуется использовать встроенную форму.
Взаимодействия между сокетами IPv4/v6
Поведение сокета AF_INET6
TCP/UDP задокументировано в спецификации RFC 2553, которая гласит:
AF_INET6
( bind() с конкретным адресом) должна принимать трафик IPv6 только по этому адресу.
AF_INET6
( bind() с адресом IPv6 ::), и на этом TCP/UDP-порту нет сокета AF_INET
со специальными подстановочными символами, то трафик IPv6 так же как и трафик IPv4 должен быть направлен на сокет AF_INET6
. Трафик IPv4 должен восприниматься приложением, как если бы оно пришло с IPv6-адреса, например ::ffff:10.1.1.1. Это называется смапированным IPv4 адресом address.
AF_INET
, так и сокеты AF_INET6
со специальными подстановочными символами, они должны работать независимо: трафик IPv4 должен маршрутизироваться на сокет AF_INET
, а IPv6 должен направляться на AF_INET6
сокет. Однако спецификация RFC 2553 не определяет ограничения между порядком привязки или тем, как номера портов TCP/UDP IPv4 и номера портов TCP/UDP IPv6 соотносятся друг с другом (должны ли они быть интегрированы или разделены). Поведение сильно отличается от реализации к реализации. Не следует полагаться на поведение сокета со специальными подстановочными символами AF_INET6
. Вместо этого следует подключиться к двум сокетам, одному для AF_INET
и другому для AF_INET6
, если требуется принимать как трафик IPv4, так и IPv6.
![]() | Следует соблюдать осторожность при обработке подключений со смапированных адресов IPv4 с сокетами AF_INET6 - если целевой узел направляет трафик IPv4 на сокеты AF_INET6 , злоумышленники могут обойти защиту. |
Из-за бреши в безопасности, по умолчанию NetBSD не направляет трафик IPv4 на сокеты AF_INET6
. Если требуется принимать трафик IPv4 и IPv6, следует использовать два сокета. Трафик IPv4 может маршрутизироваться с несколькими конфигурациями для каждого сокета/узла, однако такое поведение не рекомендуется. См. подробности в IP6.
![]() | Поддержка IPv6 может меняться по мере развития Интернет-протоколов. Не следует закладывать зависимость от деталей текущей реализации, а также от экспортируемых сервисов/служб. Рекомендуется как можно больше реализовать код, не зависящий от версии протокола, поскольку в дальнейшем нужно будет поддерживать как INET, так и INET6. |
ICMP, ICMP6, IP6, IP, TCP, UDP протоколы
bind(), connect(), getaddrinfo(), ioctl(), sendto(), socket(), sysctl()
ftp, ping6, telnet в Справочнике по Утилитам
Основано на RFC 2553, RFC 2292
Предыдущий раздел: Описание API сетевой библиотеки