Open raggi opened 5 years ago
Windows also has this api, although that doc instead recommends:
The if_nametoindex function is implemented for portability of applications with Unix environments, but the ConvertInterface functions are preferred. The if_nametoindex function can be replaced by a call to the ConvertInterfaceNameToLuidA function to convert the ANSI interface name to a NET_LUID followed by a call to the ConvertInterfaceLuidToIndex to convert the NET_LUID to the local interface index.
As another data point, I also ran into this recently and was surprised / confused.
Doing a quick survey of programs, I found ping6
works with the textual scope id, e.g. ping6 fe80::004:06ff:fe08:0a0c%en0
, while Scapy does not.
The relevant RFC here seems to be RFC 4007 which shows both the interface indices and names:
fe80::1234%1
ff02::5678%5
ff08::9abc%10
fe80::1234%ne0
ff02::5678%pvc1.3
ff08::9abc%interface10
As it stands, Rust is not compliant with IETF specifications for IP addresses, which happens to be the exact situation cited by the std-dev-guide as a situation where it may be necessary to introduce a breaking change:
Behavioral changes to stable functions generally can't be accepted. [...] An exception is when a behavior is specified in an RFC (such as IETF specifications for IP addresses). If a behavioral change fixes non-conformance then it can be considered a bug fix. In these cases, @rust-lang/libs should still be pinged for input.
The struct is currently this:
pub struct SocketAddrV6 {
ip: Ipv6Addr,
port: u16,
flowinfo: u32,
scope_id: u32,
}
I suspect we could reduce the breakage by:
scope_name: &str
field,SocketAddrV6::new()
constructor, butSocketAddrV6::scope_name()
and SocketAddrV6::set_scope_name(&str)
)Parser
to create a SocketAddrV6
and then call set_scope_name()
or set_scope_id()
depending on whether the value is all decimal digits or notSocketAddrV6
to a string, if scope_name
is set use that, if scope_id
is set use that, otherwise use neither@rust-lang/libs - input please?
I also stumbled into this recently. This would be really nice to have.
Consider the following link local IPv6 sockaddr string:
[fe80::f03c:91ff:fedf:75ee%eth0]:8080
This address does not parse or round-trip: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b36d93fe7d2a8699397c6dfafa2a3edf
The output formatting also elides the scopeid, which means that printed addresses are not valid addresses - particularly on multi-homed devices, where the un-scoped address will not function.
I believe that the correct change here is to both parse scopeid's and to include non-zero scopeids in Display. I'm happy to implement this if that is agreeable? It would need to take a dependency on
if_nametoindex
andif_indextoname
(POSIX, net/if.h) in order to function on most Unix style platforms.