From 72667185f6f45dd6cf1a4d24b6dcb5085c803f59 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 16 Oct 2022 15:05:59 +0200 Subject: [PATCH] add `ifreq` and friends for linux --- libc-test/build.rs | 5 ++- libc-test/semver/linux.txt | 2 + src/unix/linux_like/linux/mod.rs | 69 ++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/libc-test/build.rs b/libc-test/build.rs index 2fc7cc4540e0f..d5bf3ea61ba39 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -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", @@ -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 { diff --git a/libc-test/semver/linux.txt b/libc-test/semver/linux.txt index dc4bead28d4e1..96be968d8b6c8 100644 --- a/libc-test/semver/linux.txt +++ b/libc-test/semver/linux.txt @@ -2971,6 +2971,8 @@ idtype_t if_freenameindex if_nameindex ifaddrs +ifreq +in6_ifreq in6_pktinfo in6_rtmsg in_pktinfo diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs index 43f6399e442b3..4421906a4b77d 100644 --- a/src/unix/linux_like/linux/mod.rs +++ b/src/unix/linux_like/linux/mod.rs @@ -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! { @@ -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! { @@ -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() + } + } } }