Endianness of IPv6 addresses in binary/bytes sequences seem to be in big endian in all C structs, among them the Linux kernel, and WinSock/Windows, also when in memory of Intel/little endian machines.
https://www.rfc-editor.org/rfc/rfc2553
https://learn.microsoft.com/en-us/windo ... dr-in_addr
https://learn.microsoft.com/en-us/windo ... r-in6_addr
All members of the IN6_ADDR structure must be specified in network-byte-order (big-endian).
https://docs.huihoo.com/doxygen/linux/k ... _addr.html
Code: Select all
union {
__u8 u6_addr8 [16]
__be16 u6_addr16 [8]
__be32 u6_addr32 [4]
} in6_u;
// __be16 is defined as a uint16_t that must be in big endian (ensured by a static analysis tool called "Sparse")
// __be32 is defined as a uint32_t that must be in big endian (ensured by a static analysis tool called "Sparse")
IP addresses can be represented as a sequence of uint8_t, uint16_t and uint32_t, but each time all the array elements are in big endian, so that a union of the various possible subdivisions of an IP address into units of different sizes remains consistent: for example, the little endian ordered types uint16_t[8] and uint32_t[4] would not result in the same byte array, and are therefore not a correct/valid encoding.
Taking the Linux kernel in6_u union as an example:
Code: Select all
in6_u ip_addr;
// this line should have the same effect...
ip_addr.u6_addr32[0] = 0x12345678;
// ... as the following two lines
ip_addr.u6_addr16[0] = 0x1234;
ip_addr.u6_addr16[1] = 0x5678;
// assertion fails if either u6_addr16 or u6_addr32 or both are not in big endian order
assert(ip_addr.u6_addr32[0] == 0x12345678);
So, even when IP addresses are seen as a sequence of unit16_t units, they have to be in big endian. So the best approach would be to byte swap (change the byte order) of the full 16 bytes of an IP address, and not to byte swap individual uint16_t units, or other subdivisions of the IP address. Possibly some programs store IP addresses using structs that are not big endian in memory, but that would be a non-standard approach (see documentation links above) and would require supporting specific structs and their specific subdivisions/endianness requirements.
Therefore the only "obvious" non-big-endian case is to reverse the order of all bytes in one go, not parts individually. In other words, IPv6 should be treated like a big endian integer of 128 bits (16 bytes) that may have been stored entirely in big endian or in little endian format, any other internal structure has too many possible variations to consider, and would need to be handled by defining individual data type converters (or better, by a manually defined struct for a specific use case).