Skip to content
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

implement ifreq for linux #2960

Merged
merged 1 commit into from Oct 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion libc-test/build.rs
Expand Up @@ -2887,6 +2887,7 @@ fn test_linux(target: &str) {
"linux/if_ether.h",
"linux/if_tun.h",
"linux/input.h",
"linux/ipv6.h",
"linux/keyctl.h",
"linux/magic.h",
"linux/memfd.h",
Expand Down Expand Up @@ -3479,7 +3480,9 @@ fn test_linux(target: &str) {
(struct_ == "user_fpsimd_struct" && field == "vregs") ||
// Linux >= 5.11 tweaked the `svm_zero` field of the `sockaddr_vm` struct.
// https://github.com/torvalds/linux/commit/dc8eeef73b63ed8988224ba6b5ed19a615163a7f
(struct_ == "sockaddr_vm" && field == "svm_zero")
(struct_ == "sockaddr_vm" && field == "svm_zero") ||
// the `ifr_ifru` field is an anonymous union
(struct_ == "ifreq" && field == "ifr_ifru")
});

cfg.skip_roundtrip(move |s| match s {
Expand Down
2 changes: 2 additions & 0 deletions libc-test/semver/linux.txt
Expand Up @@ -2971,6 +2971,8 @@ idtype_t
if_freenameindex
if_nameindex
ifaddrs
ifreq
in6_ifreq
in6_pktinfo
in6_rtmsg
in_pktinfo
Expand Down
69 changes: 69 additions & 0 deletions src/unix/linux_like/linux/mod.rs
Expand Up @@ -603,6 +603,21 @@ s! {
pub src_length: ::__u64,
pub dest_offset: ::__u64,
}

pub struct __c_anonymous_ifru_map {
pub mem_start: ::c_ulong,
pub mem_end: ::c_ulong,
pub base_addr: ::c_ushort,
pub irq: ::c_uchar,
pub dma: ::c_uchar,
pub port: ::c_uchar,
}

pub struct in6_ifreq {
pub ifr6_addr: ::in6_addr,
pub ifr6_prefixlen: u32,
pub ifr6_ifindex: ::c_int,
}
}

s_no_extra_traits! {
Expand Down Expand Up @@ -690,6 +705,32 @@ s_no_extra_traits! {
#[cfg(not(all(target_arch = "x86_64", target_pointer_width = "32")))]
pad: [::c_long; 4],
}

#[cfg(libc_union)]
pub union __c_anonymous_ifr_ifru {
pub ifru_addr: ::sockaddr,
pub ifru_dstaddr: ::sockaddr,
pub ifru_broadaddr: ::sockaddr,
pub ifru_netmask: ::sockaddr,
pub ifru_hwaddr: ::sockaddr,
pub ifru_flags: ::c_short,
pub ifru_ifindex: ::c_int,
pub ifru_metric: ::c_int,
pub ifru_mtu: ::c_int,
pub ifru_map: __c_anonymous_ifru_map,
pub ifru_slave: [::c_char; ::IFNAMSIZ],
pub ifru_newname: [::c_char; ::IFNAMSIZ],
pub ifru_data: *mut ::c_char,
}

pub struct ifreq {
/// interface name, e.g. "en0"
pub ifr_name: [::c_char; ::IFNAMSIZ],
#[cfg(libc_union)]
pub ifr_ifru: __c_anonymous_ifr_ifru,
#[cfg(not(libc_union))]
pub ifr_ifru: ::sockaddr,
}
}

s_no_extra_traits! {
Expand Down Expand Up @@ -1063,6 +1104,34 @@ cfg_if! {
self.mq_curmsgs.hash(state);
}
}
#[cfg(libc_union)]
impl ::fmt::Debug for __c_anonymous_ifr_ifru {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("ifr_ifru")
.field("ifru_addr", unsafe { &self.ifru_addr })
.field("ifru_dstaddr", unsafe { &self.ifru_dstaddr })
.field("ifru_broadaddr", unsafe { &self.ifru_broadaddr })
.field("ifru_netmask", unsafe { &self.ifru_netmask })
.field("ifru_hwaddr", unsafe { &self.ifru_hwaddr })
.field("ifru_flags", unsafe { &self.ifru_flags })
.field("ifru_ifindex", unsafe { &self.ifru_ifindex })
.field("ifru_metric", unsafe { &self.ifru_metric })
.field("ifru_mtu", unsafe { &self.ifru_mtu })
.field("ifru_map", unsafe { &self.ifru_map })
.field("ifru_slave", unsafe { &self.ifru_slave })
.field("ifru_newname", unsafe { &self.ifru_newname })
.field("ifru_data", unsafe { &self.ifru_data })
.finish()
}
}
impl ::fmt::Debug for ifreq {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("ifreq")
.field("ifr_name", &self.ifr_name)
.field("ifr_ifru", &self.ifr_ifru)
.finish()
}
}
}
}

Expand Down