On 30.06.2018 21:33, Rick Macklem wrote: >> I'm unaware of applicability of IPv6 addresses with restricted scope in >> this area, but when you use inet_ntop() to get IPv6 address text >> representation, you can lost IPv6 scope zone id. getaddrinfo() can >> return sockaddr structure with properly filled sin6_scope_id field. It >> is better to use getnameinfo() with NI_NUMERICHOST flag. Also the size >> of ip6 buffer should be enough to keep scope specifier. > Thanks for mentioning this. First off, you could write what I know about IPv6 > addresses on a very small postage stamp... > > Are you referring to the 4bits in the second octet of the address or the > stuff that > can end up as a suffix starting with"%"?
RFC4007 defines scopes of IPv6 addresses. The important part of this is that a host can have several interfaces (links) and each interface can have the same unicast IPv6 address, but the scope of these addresses will be restricted by these links. I.e. IPv6 link-local address from e.g. igb0 interface can be used only within igb0, and the same address on the igb1 interface can be used only within igb1. And neighbor hosts on these links can have the same addresses, but they will not be reachable: [neighbor1 fe80::100]<-->[fe80::1%igb0 | fe80::1%igb1]<-->[fe80::100 neighbor2] neighbor1 can not reach neighbor2, since these addresses belongs to different scope zones. On the host with two interfaces you as user can use link-local addresses and can specify such addresses in application. To disambiguate them you must specify scope zone identifier, "%igb0" or "%igb1". E.g. if you want to connect with neighbor1, you can use "telnet fe80::100%igb0 someport" and the kernel will initiate connection with neighbor1 through igb0. inet_ntop() call doesn't support this. KAME-based IPv6 stack uses the second 16-bits word of the address to store scope zone id. It is hack and user applications should not use it, and should not rely on this hack. The struct sockaddr_in6 has special field sin6_scope_id to specify scope zone id. Note, that the size of this field is 32-bits. If you want to support such addresses, you need to use scope zones aware API - getaddrinfo()/getnameinfo(). Together with using such API you will need to use struct sockaddr_in6, or keep zone id separately. In the kernel when you operate with IPv6 link-local addresses you need to properly prepare them in the IPv6 header, i.e. embed scope zone identifier. Otherwise the kernel will fail to send such packets. > In this case, the address string is put "on the wire" for the client to use > to connect > to a data server (DS). I'm not sure if the "%..." stuff is useful in this > case and, > when it gets to the client, it will be translated to an address via the kernel > version of inet_pton(), which does not parse "%..." as far as I can see. > > So maybe others can clarify if it would be better to use getnameinfo() for > this > use case? -- WBR, Andrey V. Elsukov
signature.asc
Description: OpenPGP digital signature