-
Notifications
You must be signed in to change notification settings - Fork 692
Unclear how to work with LinkAddr / sockaddr_ll #2059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What are you trying to do anyway? Change an interface's mac address? There is a good reason why the inner |
Working with packet(7) sockets basically needs options to at least modify From the manpage: By default, all packets of the specified protocol type are passed to a packet socket. To get packets only from
a specific interface use bind(2) specifying an address in a struct sockaddr_ll to bind the packet socket to an
interface. Fields used for binding are sll_family (should be AF_PACKET), sll_protocol, and sll_ifindex. When sending this structure is used to specify destination infromation when using From the manpage: When you send packets, it is enough to specify sll_family, sll_addr, sll_halen, sll_ifindex, and sll_protocol.
The other fields should be 0. sll_hatype and sll_pkttype are set on received packets for your information. In both cases So what I basically would need would be either: A way to derive a Or: A way to construct a |
Thinking about this a little more. As one could get information about new interfaces becoming available through eg. netlink sockets, so I think I would prefer the latter. So I was thinking along the lines of: impl LinkAddr {
pub fn new(protocol: u16, ifindex: usize) -> LinkAddr;
pub fn new_with_addr(protocol: u16, ifindex: usize, addr: &[u8; 6]) -> LinkAddr;
} Note: I just noticed you're using |
I don't like the proposed constructors because they're potentially too limited. On Linux and OSX, the libc structure has 7 fields. On the BSDs, it has between 8 and 10. We don't want to define a new constructor for every combination of fields that the user might want to initialize. I think it would be better to either use the Builder pattern, or else rely on getifaddrs to initialize the structure, and then provide mutators as necessary. Regarding |
We a use case with a raw socket (EtherCAT) where we currently do let sll = &libc::sockaddr_ll {
sll_family: libc::AF_PACKET as u16,
sll_ifindex: index.try_into()?,
sll_protocol: ethertype.to_be(),
sll_addr: [0; LENGTH_PHYSICAL_LAYER_ADDR],
sll_halen: 0,
sll_hatype: 0,
sll_pkttype: 0,
};
let ssl_len = std::mem::size_of_val(sll).try_into()?;
let laddr = unsafe {
LinkAddr::from_raw(
sll as *const libc::sockaddr_ll as *const sockaddr,
Some(ssl_len),
)
}
.ok_or(Error::Configuration("sockaddr_ll is invalid".to_string()))?; Is there anything preventing you from providing a safe constructor that just takes in the impl LinkAddr {
pub fn new(sll: libc::sockaddr_ll) -> Self {
Self(sll)
}
} |
Yes. We can't provide a safe |
Currently I can't seem to find any way to create a new LinkAddr or modify a LinkAddr.
The only way I'm able to get a LinkAddr is through
getifaddrs()
. But after that I'm unable to change eg.sll_protocol
to some specific protocol. I can turnLinkAddr
into asockaddr_ll
(as_ref().to_owned()
) and change it that way, but then I can't turn it back into aLinkAddr
without usingunsafe
.Is there a good reason why one shouldn't be able to get mutable access to the
sockaddr_ll
inside an ownedLinkAddr
? Or should that be done through mutators on theLinkAddr
(I'll make an MR in a heartbeat :-))Or would adding a constructor or
impl From<sockaddr_ll> for LinkAddr
be more idiomatic to the way these types are meant to be used?The text was updated successfully, but these errors were encountered: