diff --git a/libc-test/build.rs b/libc-test/build.rs index 1b65d65f95ec9..27edaacca4f71 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -3332,7 +3332,6 @@ fn test_linux(target: &str) { "netinet/ip.h", "netinet/tcp.h", "netinet/udp.h", - "netpacket/packet.h", "poll.h", "pthread.h", "pty.h", @@ -3432,6 +3431,7 @@ fn test_linux(target: &str) { "linux/if_addr.h", "linux/if_alg.h", "linux/if_ether.h", + "linux/if_packet.h", "linux/if_tun.h", "linux/if_xdp.h", "linux/input.h", @@ -3608,6 +3608,23 @@ fn test_linux(target: &str) { if (gnu && sparc64) && (ty == "ip_mreqn" || ty == "hwtstamp_config") { return true; } + // FIXME: pass by value for structs that are not an even 32/64 bits on + // big-endian systems corrupts the value for unknown reasons. + if (sparc64 || ppc || ppc64 || s390x) + && (ty == "sockaddr_pkt" + || ty == "tpacket_auxdata" + || ty == "tpacket_hdr_variant1" + || ty == "tpacket_req3" + || ty == "tpacket_stats_v3" + || ty == "tpacket_req_u") + { + return true; + } + // FIXME: musl doesn't compile with `struct fanout_args` for unknown reasons. + if musl && ty == "fanout_args" { + return true; + } + match ty { // These cannot be tested when "resolv.h" is included and are tested // in the `linux_elf.rs` file. diff --git a/libc-test/semver/linux.txt b/libc-test/semver/linux.txt index ff82d18b355ee..07e93fee31ee4 100644 --- a/libc-test/semver/linux.txt +++ b/libc-test/semver/linux.txt @@ -1799,11 +1799,38 @@ O_RSYNC O_SYNC O_TMPFILE PACKET_ADD_MEMBERSHIP +PACKET_AUXDATA +PACKET_BROADCAST PACKET_DROP_MEMBERSHIP +PACKET_FANOUT +PACKET_FANOUT_CBPF +PACKET_FANOUT_CPU +PACKET_FANOUT_FLAG_DEFRAG +PACKET_FANOUT_FLAG_ROLLOVER +PACKET_FANOUT_FLAG_UNIQUEID +PACKET_FANOUT_HASH +PACKET_FANOUT_LB +PACKET_FANOUT_QM +PACKET_FANOUT_RND +PACKET_FANOUT_ROLLOVER +PACKET_HOST +PACKET_KERNEL +PACKET_LOOPBACK +PACKET_LOSS PACKET_MR_ALLMULTI PACKET_MR_MULTICAST PACKET_MR_PROMISC PACKET_MR_UNICAST +PACKET_MULTICAST +PACKET_OTHERHOST +PACKET_OUTGOING +PACKET_QDISC_BYPASS +PACKET_RESERVE +PACKET_RX_RING +PACKET_STATISTICS +PACKET_TIMESTAMP +PACKET_USER +PACKET_VERSION PENDIN PF_ALG PF_APPLETALK @@ -3190,6 +3217,22 @@ TLS_GET_RECORD_TYPE TLS_RX TLS_SET_RECORD_TYPE TLS_TX +TP_STATUS_AVAILABLE +TP_STATUS_BLK_TMO +TP_STATUS_COPY +TP_STATUS_CSUMNOTREADY +TP_STATUS_CSUM_VALID +TP_STATUS_KERNEL +TP_STATUS_LOSING +TP_STATUS_SENDING +TP_STATUS_SEND_REQUEST +TP_STATUS_TS_RAW_HARDWARE +TP_STATUS_TS_SOFTWARE +TP_STATUS_TS_SYS_HARDWARE +TP_STATUS_USER +TP_STATUS_VLAN_TPID_VALID +TP_STATUS_VLAN_VALID +TP_STATUS_WRONG_FORMAT TUN_READQ_SIZE TUN_TAP_DEV TUN_TUN_DEV @@ -3452,6 +3495,7 @@ fanotify_event_metadata fanotify_init fanotify_mark fanotify_response +fanout_args fchdir fdatasync fdopendir @@ -3819,6 +3863,7 @@ sockaddr_alg sockaddr_can sockaddr_ll sockaddr_nl +sockaddr_pkt sockaddr_vm splice spwd @@ -3853,6 +3898,22 @@ timer_getoverrun timer_gettime timer_settime tmpfile64 +tpacket2_hdr +tpacket3_hdr +tpacket_auxdata +tpacket_bd_header_u +tpacket_bd_ts +tpacket_block_desc +tpacket_hdr +tpacket_hdr_v1 +tpacket_hdr_variant1 +tpacket_req +tpacket_req3 +tpacket_req_u +tpacket_rollover_stats +tpacket_stats +tpacket_stats_v3 +tpacket_versions truncate truncate64 ttyname_r diff --git a/src/unix/linux_like/linux/mod.rs b/src/unix/linux_like/linux/mod.rs index acb10c603f725..834cf8a9a1387 100644 --- a/src/unix/linux_like/linux/mod.rs +++ b/src/unix/linux_like/linux/mod.rs @@ -58,6 +58,14 @@ missing! { pub enum fpos64_t {} // FIXME: fill this out with a struct } +e! { + pub enum tpacket_versions { + TPACKET_V1, + TPACKET_V2, + TPACKET_V3, + } +} + s! { pub struct glob_t { pub gl_pathc: ::size_t, @@ -140,6 +148,15 @@ s! { __val: [::c_int; 2], } + pub struct fanout_args { + #[cfg(target_endian = "little")] + pub id: ::__u16, + pub type_flags: ::__u16, + #[cfg(target_endian = "big")] + pub id: ::__u16, + pub max_num_members: ::__u32, + } + pub struct packet_mreq { pub mr_ifindex: ::c_int, pub mr_type: ::c_ushort, @@ -147,6 +164,116 @@ s! { pub mr_address: [::c_uchar; 8], } + pub struct sockaddr_pkt { + pub spkt_family: ::c_ushort, + pub spkt_device: [::c_uchar; 14], + pub spkt_protocol: ::c_ushort, + } + + pub struct tpacket_auxdata { + pub tp_status: ::__u32, + pub tp_len: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub tp_vlan_tci: ::__u16, + pub tp_vlan_tpid: ::__u16, + } + + pub struct tpacket_hdr { + pub tp_status: ::c_ulong, + pub tp_len: ::c_uint, + pub tp_snaplen: ::c_uint, + pub tp_mac: ::c_ushort, + pub tp_net: ::c_ushort, + pub tp_sec: ::c_uint, + pub tp_usec: ::c_uint, + } + + pub struct tpacket_hdr_variant1 { + pub tp_rxhash: ::__u32, + pub tp_vlan_tci: ::__u32, + pub tp_vlan_tpid: ::__u16, + pub tp_padding: ::__u16, + } + + pub struct tpacket2_hdr { + pub tp_status: ::__u32, + pub tp_len: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub tp_sec: ::__u32, + pub tp_nsec: ::__u32, + pub tp_vlan_tci: ::__u16, + pub tp_vlan_tpid: ::__u16, + pub tp_padding: [::__u8; 4], + } + + pub struct tpacket_req { + pub tp_block_size: ::c_uint, + pub tp_block_nr: ::c_uint, + pub tp_frame_size: ::c_uint, + pub tp_frame_nr: ::c_uint, + } + + pub struct tpacket_req3 { + pub tp_block_size: ::c_uint, + pub tp_block_nr: ::c_uint, + pub tp_frame_size: ::c_uint, + pub tp_frame_nr: ::c_uint, + pub tp_retire_blk_tov: ::c_uint, + pub tp_sizeof_priv: ::c_uint, + pub tp_feature_req_word: ::c_uint, + } + + #[repr(align(8))] + pub struct tpacket_rollover_stats { + pub tp_all: ::__u64, + pub tp_huge: ::__u64, + pub tp_failed: ::__u64, + } + + pub struct tpacket_stats { + pub tp_packets: ::c_uint, + pub tp_drops: ::c_uint, + } + + pub struct tpacket_stats_v3 { + pub tp_packets: ::c_uint, + pub tp_drops: ::c_uint, + pub tp_freeze_q_cnt: ::c_uint, + } + + pub struct tpacket3_hdr { + pub tp_next_offset: ::__u32, + pub tp_sec: ::__u32, + pub tp_nsec: ::__u32, + pub tp_snaplen: ::__u32, + pub tp_len: ::__u32, + pub tp_status: ::__u32, + pub tp_mac: ::__u16, + pub tp_net: ::__u16, + pub hv1: ::tpacket_hdr_variant1, + pub tp_padding: [::__u8; 8], + } + + pub struct tpacket_bd_ts { + pub ts_sec: ::c_uint, + pub ts_usec: ::c_uint, + } + + #[repr(align(8))] + pub struct tpacket_hdr_v1 { + pub block_status: ::__u32, + pub num_pkts: ::__u32, + pub offset_to_first_pkt: ::__u32, + pub blk_len: ::__u32, + pub seq_num: ::__u64, + pub ts_first_pkt: ::tpacket_bd_ts, + pub ts_last_pkt: ::tpacket_bd_ts, + } + pub struct cpu_set_t { #[cfg(all(target_pointer_width = "32", not(target_arch = "x86_64")))] @@ -889,6 +1016,21 @@ s_no_extra_traits! { pub sched_deadline: ::__u64, pub sched_period: ::__u64, } + + pub union tpacket_req_u { + pub req: ::tpacket_req, + pub req3: ::tpacket_req3, + } + + pub union tpacket_bd_header_u { + pub bh1: ::tpacket_hdr_v1, + } + + pub struct tpacket_block_desc { + pub version: ::__u32, + pub offset_to_priv: ::__u32, + pub hdr: ::tpacket_bd_header_u, + } } s_no_extra_traits! { @@ -1313,6 +1455,33 @@ cfg_if! { } } + impl ::fmt::Debug for tpacket_req_u { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("tpacket_req_u") + .field("req3", unsafe { &self.req3 }) + .finish() + } + } + + impl ::fmt::Debug for tpacket_bd_header_u { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("tpacket_bd_header_u") + .field("bh1", unsafe { &self.bh1 }) + .finish() + } + } + + impl ::fmt::Debug for tpacket_block_desc { + fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { + f.debug_struct("tpacket_bd_header_u") + .field("version", &self.version) + .field("offset_to_priv", &self.offset_to_priv) + .field("hdr", &self.hdr) + .finish() + } + } + + #[cfg(libc_union)] impl ::fmt::Debug for __c_anonymous_ifc_ifcu { fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result { @@ -2820,12 +2989,73 @@ pub const CTRL_ATTR_MCAST_GRP_NAME: ::c_int = 1; pub const CTRL_ATTR_MCAST_GRP_ID: ::c_int = 2; // linux/if_packet.h +pub const PACKET_HOST: ::c_uchar = 0; +pub const PACKET_BROADCAST: ::c_uchar = 1; +pub const PACKET_MULTICAST: ::c_uchar = 2; +pub const PACKET_OTHERHOST: ::c_uchar = 3; +pub const PACKET_OUTGOING: ::c_uchar = 4; +pub const PACKET_LOOPBACK: ::c_uchar = 5; +pub const PACKET_USER: ::c_uchar = 6; +pub const PACKET_KERNEL: ::c_uchar = 7; + pub const PACKET_ADD_MEMBERSHIP: ::c_int = 1; pub const PACKET_DROP_MEMBERSHIP: ::c_int = 2; - +pub const PACKET_RX_RING: ::c_int = 5; +pub const PACKET_STATISTICS: ::c_int = 6; +pub const PACKET_AUXDATA: ::c_int = 8; +pub const PACKET_VERSION: ::c_int = 10; +pub const PACKET_RESERVE: ::c_int = 12; +pub const PACKET_TX_RING: ::c_int = 13; +pub const PACKET_LOSS: ::c_int = 14; +pub const PACKET_TIMESTAMP: ::c_int = 17; +pub const PACKET_FANOUT: ::c_int = 18; +pub const PACKET_QDISC_BYPASS: ::c_int = 20; + +pub const PACKET_FANOUT_HASH: ::c_uint = 0; +pub const PACKET_FANOUT_LB: ::c_uint = 1; +pub const PACKET_FANOUT_CPU: ::c_uint = 2; +pub const PACKET_FANOUT_ROLLOVER: ::c_uint = 3; +pub const PACKET_FANOUT_RND: ::c_uint = 4; +pub const PACKET_FANOUT_QM: ::c_uint = 5; +pub const PACKET_FANOUT_CBPF: ::c_uint = 6; +pub const PACKET_FANOUT_EBPF: ::c_uint = 7; +pub const PACKET_FANOUT_FLAG_ROLLOVER: ::c_uint = 0x1000; +pub const PACKET_FANOUT_FLAG_UNIQUEID: ::c_uint = 0x2000; +pub const PACKET_FANOUT_FLAG_DEFRAG: ::c_uint = 0x8000; + pub const PACKET_MR_MULTICAST: ::c_int = 0; pub const PACKET_MR_PROMISC: ::c_int = 1; pub const PACKET_MR_ALLMULTI: ::c_int = 2; + +pub const TP_STATUS_KERNEL: ::__u32 = 0; +pub const TP_STATUS_USER: ::__u32 = 1 << 0; +pub const TP_STATUS_COPY: ::__u32 = 1 << 1; +pub const TP_STATUS_LOSING: ::__u32 = 1 << 2; +pub const TP_STATUS_CSUMNOTREADY: ::__u32 = 1 << 3; +pub const TP_STATUS_VLAN_VALID: ::__u32 = 1 << 4; +pub const TP_STATUS_BLK_TMO: ::__u32 = 1 << 5; +pub const TP_STATUS_VLAN_TPID_VALID: ::__u32 = 1 << 6; +pub const TP_STATUS_CSUM_VALID: ::__u32 = 1 << 7; + +pub const TP_STATUS_AVAILABLE: ::__u32 = 0; +pub const TP_STATUS_SEND_REQUEST: ::__u32 = 1 << 0; +pub const TP_STATUS_SENDING: ::__u32 = 1 << 1; +pub const TP_STATUS_WRONG_FORMAT: ::__u32 = 1 << 2; + +pub const TP_STATUS_TS_SOFTWARE: ::__u32 = 1 << 29; +pub const TP_STATUS_TS_SYS_HARDWARE: ::__u32 = 1 << 30; +pub const TP_STATUS_TS_RAW_HARDWARE: ::__u32 = 1 << 31; + +pub const TPACKET_ALIGNMENT: usize = 16; +pub const TPACKET_HDRLEN: usize = ((core::mem::size_of::<::tpacket_hdr>() + TPACKET_ALIGNMENT - 1) + & !(TPACKET_ALIGNMENT - 1)) + + core::mem::size_of::<::sockaddr_ll>(); +pub const TPACKET2_HDRLEN: usize = + ((core::mem::size_of::<::tpacket2_hdr>() + TPACKET_ALIGNMENT - 1) & !(TPACKET_ALIGNMENT - 1)) + + core::mem::size_of::<::sockaddr_ll>(); +pub const TPACKET3_HDRLEN: usize = + ((core::mem::size_of::<::tpacket3_hdr>() + TPACKET_ALIGNMENT - 1) & !(TPACKET_ALIGNMENT - 1)) + + core::mem::size_of::<::sockaddr_ll>(); // linux/netfilter.h pub const NF_DROP: ::c_int = 0; @@ -4788,6 +5018,10 @@ f! { ee.offset(1) as *mut ::sockaddr } + pub fn TPACKET_ALIGN(x: usize) -> usize { + (x + TPACKET_ALIGNMENT - 1) & !(TPACKET_ALIGNMENT - 1) + } + pub fn BPF_RVAL(code: ::__u32) -> ::__u32 { code & 0x18 }