Сетевой порядок байт бессмысленно в IPv6?


Если мы используем 32-разрядное целое число для хранения адреса IPv4, то необходимо учитывать порядок байтов целого числа.

Однако, поскольку почти на всех платформах нет встроенного 128-битного целочисленного типа, IPv6-адрес должен храниться в массиве байтов, поэтому я думаю, что порядок байтов больше не является проблемой.

Я прав? Или есть соответствующая функция htonlXXX для IPv6?

5 2

5 ответов:

IPv6 требует сетевого порядка байтов для адресов ipv6. hton и ntoh - это все о преобразовании адреса из того, как он хранится в вашем коде, в то, как он должен храниться в пакете (и наоборот). Таким образом, проблема заключается в том, как он хранится в вашем коде.

Кроме того, определение IPv6-адреса в коде может позволить использовать больше способов его адресации, чем просто массив байтов:

struct in6_addr
{
    union 
    {
        __u8 u6_addr8[16];
        __u16 u6_addr16[8];
        __u32 u6_addr32[4];
    } in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};

IPv6-адреса для пользователя представлены в виде 8 16-битных значений. Если у вас есть адрес хранится в виде 8 16-битных значений в коде, затем вам нужно будет использовать htons для каждого 16-битного значения, когда вы помещаете его в пакет, используя массив u6_addr16 [], и использовать ntohs, когда вы извлекаете каждое 16-битное значение из u6_addr16[].

Эти ссылки полезны:

Http://msdn.microsoft.com/en-us/library/ee175867.aspx

Http://en.wikipedia.org/wiki/IPv6_address (особенно диаграмма вверху справа)

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

Однако, поскольку почти на всех платформах нет встроенного 128-битного целочисленного типа, IPv6-адрес должен храниться в массиве байтов, поэтому я думаю, что порядок байтов больше не является проблемой.

Этого не следует; когда вы строите массив байтов, вы все еще должны рассмотреть, упаковываете ли Вы данные в порядке 0123456789ABCDEF или FEDCBA976543210. По-прежнему требуется правильный порядок байтов, просто такие функции, как ntohl() и htonl(), не применимы в создание 128-битного адреса.

Если вы генерируете двоичный адрес из формы "presentation" с помощью inet_ntop(), например, вам не нужно самостоятельно рассматривать порядок байтов для любого типа адреса. Порядок байтов по-прежнему важен, но API будет обрабатывать его за вас.

Специфическая причина, по которой вы должны уделять пристальное внимание порядку байтов при обработке адресов IPv4 и номеров портов, заключается в том, что структуры sockaddr_in и in_addr имеют элементы данных с целочисленными типами, большими, чем char, и содержимое которых должно быть в сетевом порядке байтов.

Даже с IPv4 вы можете не беспокоиться о порядке байтов адресной части этого -- используйте inet_aton или inet_pton для заполнения in_addr непосредственно из строки. Последняя функция делает IPv6-адреса тоже (заполнение an in6_addr).

При использовании IPv6 вам все еще нужно htons для номера порта, и вам понадобится преобразование хоста/сети, Если вы решите получить доступ к in6_addr кусками больше байта.

Как вы сказали, если ваша платформа не имеет 128-битного типа, то вы не можете получить доступ к in6_addr как к одному 128-битному фрагменту так, как вы могли бы получить доступ к in_addr как к одному 32-битному фрагменту. Но если какой-то сетевой интерфейс / реализация с 128-битным типом когда-либо решит предоставить 128-битное представление он, тогда, надеюсь, он также обеспечит соответствующие функции ntohX и htonX.
struct in6_addr{
  uint8_t s6_addr[16];//128bit ipv6 address
};

Через эту структуру то, что вы считаете правильным.