Skip to content

Commit 4f428e0

Browse files
committed
adding ethhdr type for linux/android for proper packet filtering.
[ref](https://docs.huihoo.com/doxygen/linux/kernel/3.7/structethhdr.html)
1 parent 4abcd81 commit 4f428e0

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

libc-test/build.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,8 @@ fn test_android(target: &str) {
21052105
(struct_ == "sigaction" && field == "sa_sigaction") ||
21062106
// signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
21072107
(struct_ == "signalfd_siginfo" && field == "ssi_call_addr") ||
2108+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
2109+
(struct_ == "ethhdr" && field == "h_proto") ||
21082110
// FIXME: Seems the type has been changed on NDK r26b
21092111
(struct_ == "flock64" && (field == "l_start" || field == "l_len"))
21102112
});
@@ -3680,6 +3682,10 @@ fn test_linux(target: &str) {
36803682
if sparc64 && (ty == "Elf32_Rela" || ty == "Elf64_Rela") {
36813683
return true;
36823684
}
3685+
// FIXME: alignment issue with this arch
3686+
if loongarch64 && ty == "ethhdr" {
3687+
return true;
3688+
}
36833689
match ty {
36843690
// FIXME: `sighandler_t` type is incorrect, see:
36853691
// https://github.com/rust-lang/libc/issues/1359
@@ -4386,6 +4392,8 @@ fn test_linux(target: &str) {
43864392
(struct_ == "ptp_perout_request" && field == "anonymous_1") ||
43874393
// `anonymous_2` is an anonymous union
43884394
(struct_ == "ptp_perout_request" && field == "anonymous_2") ||
4395+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
4396+
(struct_ == "ethhdr" && field == "h_proto") ||
43894397
// FIXME(linux): `adjust_phase` requires >= 5.7 kernel headers
43904398
// FIXME(linux): `max_phase_adj` requires >= 5.19 kernel headers
43914399
// the rsv field shrunk when those fields got added, so is omitted too

libc-test/semver/android.txt

+1
Original file line numberDiff line numberDiff line change
@@ -3230,6 +3230,7 @@ epoll_create1
32303230
epoll_ctl
32313231
epoll_event
32323232
epoll_wait
3233+
ethhdr
32333234
eventfd
32343235
eventfd_read
32353236
eventfd_write

src/unix/linux_like/android/mod.rs

+39
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,11 @@ s! {
517517
pub ifr6_prefixlen: u32,
518518
pub ifr6_ifindex: c_int,
519519
}
520+
521+
// is __be16 __bitwise __u16
522+
pub struct __c_anonymous___be16 {
523+
__priv: [crate::__u8; 2],
524+
}
520525
}
521526

522527
s_no_extra_traits! {
@@ -638,6 +643,15 @@ s_no_extra_traits! {
638643
pub ifc_len: c_int,
639644
pub ifc_ifcu: __c_anonymous_ifc_ifcu,
640645
}
646+
647+
// linux/if_ether.h
648+
649+
#[repr(C, align(1))]
650+
pub struct ethhdr {
651+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
652+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
653+
pub h_proto: __c_anonymous___be16,
654+
}
641655
}
642656

643657
cfg_if! {
@@ -1020,6 +1034,31 @@ cfg_if! {
10201034
.finish()
10211035
}
10221036
}
1037+
1038+
impl Eq for ethhdr {}
1039+
1040+
impl PartialEq for ethhdr {
1041+
fn eq(&self, other: &ethhdr) -> bool {
1042+
self.h_dest
1043+
.iter()
1044+
.zip(other.h_dest.iter())
1045+
.all(|(a, b)| a == b)
1046+
&& self
1047+
.h_source
1048+
.iter()
1049+
.zip(other.h_source.iter())
1050+
.all(|(a, b)| a == b)
1051+
}
1052+
}
1053+
1054+
impl fmt::Debug for ethhdr {
1055+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1056+
f.debug_struct("ethhdr")
1057+
.field("h_dest", &self.h_dest)
1058+
.field("h_source", &self.h_source)
1059+
.finish()
1060+
}
1061+
}
10231062
}
10241063
}
10251064

src/unix/linux_like/linux/mod.rs

+43
Original file line numberDiff line numberDiff line change
@@ -1319,6 +1319,11 @@ s! {
13191319
pub propagation: crate::__u64,
13201320
pub userns_fd: crate::__u64,
13211321
}
1322+
1323+
// is __be16 __bitwise __u16
1324+
pub struct __c_anonymous___be16 {
1325+
__priv: [crate::__u8; 2],
1326+
}
13221327
}
13231328

13241329
cfg_if! {
@@ -1784,6 +1789,16 @@ s_no_extra_traits! {
17841789
pub request: xsk_tx_metadata_request,
17851790
pub completion: xsk_tx_metadata_completion,
17861791
}
1792+
1793+
// linux/if_ether.h
1794+
1795+
#[cfg(not(target_arch = "loongarch64"))]
1796+
#[repr(C, align(1))]
1797+
pub struct ethhdr {
1798+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
1799+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
1800+
pub h_proto: __c_anonymous___be16,
1801+
}
17871802
}
17881803

17891804
cfg_if! {
@@ -2211,6 +2226,34 @@ cfg_if! {
22112226
.finish()
22122227
}
22132228
}
2229+
2230+
#[cfg(not(target_arch = "loongarch64"))]
2231+
impl Eq for ethhdr {}
2232+
2233+
#[cfg(not(target_arch = "loongarch64"))]
2234+
impl PartialEq for ethhdr {
2235+
fn eq(&self, other: &ethhdr) -> bool {
2236+
self.h_dest
2237+
.iter()
2238+
.zip(other.h_dest.iter())
2239+
.all(|(a, b)| a == b)
2240+
&& self
2241+
.h_source
2242+
.iter()
2243+
.zip(other.h_source.iter())
2244+
.all(|(a, b)| a == b)
2245+
}
2246+
}
2247+
2248+
#[cfg(not(target_arch = "loongarch64"))]
2249+
impl fmt::Debug for ethhdr {
2250+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2251+
f.debug_struct("ethhdr")
2252+
.field("h_dest", &self.h_dest)
2253+
.field("h_source", &self.h_source)
2254+
.finish()
2255+
}
2256+
}
22142257
}
22152258
}
22162259

0 commit comments

Comments
 (0)