Skip to content

Commit 7357526

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 0e99e0a commit 7357526

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

libc-test/build.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,6 +2106,8 @@ fn test_android(target: &str) {
21062106
(struct_ == "sigaction" && field == "sa_sigaction") ||
21072107
// signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
21082108
(struct_ == "signalfd_siginfo" && field == "ssi_call_addr") ||
2109+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
2110+
(struct_ == "ethhdr" && field == "h_proto") ||
21092111
// FIXME: Seems the type has been changed on NDK r26b
21102112
(struct_ == "flock64" && (field == "l_start" || field == "l_len"))
21112113
});
@@ -3686,6 +3688,10 @@ fn test_linux(target: &str) {
36863688
if sparc64 && (ty == "Elf32_Rela" || ty == "Elf64_Rela") {
36873689
return true;
36883690
}
3691+
// FIXME: alignment issue with this arch
3692+
if loongarch64 && ty == "ethhdr" {
3693+
return true;
3694+
}
36893695
match ty {
36903696
// FIXME(sighandler): `sighandler_t` type is incorrect, see:
36913697
// https://github.com/rust-lang/libc/issues/1359
@@ -4395,6 +4401,8 @@ fn test_linux(target: &str) {
43954401
(struct_ == "ptp_perout_request" && field == "anonymous_1") ||
43964402
// `anonymous_2` is an anonymous union
43974403
(struct_ == "ptp_perout_request" && field == "anonymous_2") ||
4404+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
4405+
(struct_ == "ethhdr" && field == "h_proto") ||
43984406
// FIXME(linux): `adjust_phase` requires >= 5.7 kernel headers
43994407
// FIXME(linux): `max_phase_adj` requires >= 5.19 kernel headers
44004408
// the rsv field shrunk when those fields got added, so is omitted too

libc-test/semver/android.txt

Lines changed: 1 addition & 0 deletions
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

libc-test/semver/linux-gnu.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,7 @@ dlmopen
588588
eaccess
589589
endutxent
590590
epoll_pwait2
591+
ethhdr
591592
euidaccess
592593
execveat
593594
explicit_bzero

src/unix/linux_like/android/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub type __u16 = c_ushort;
3434
pub type __s16 = c_short;
3535
pub type __u32 = c_uint;
3636
pub type __s32 = c_int;
37+
pub type __be16 = __u16;
3738

3839
// linux/elf.h
3940

@@ -638,6 +639,15 @@ s_no_extra_traits! {
638639
pub ifc_len: c_int,
639640
pub ifc_ifcu: __c_anonymous_ifc_ifcu,
640641
}
642+
643+
// linux/if_ether.h
644+
645+
#[repr(C, packed)]
646+
pub struct ethhdr {
647+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
648+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
649+
pub h_proto: crate::__be16,
650+
}
641651
}
642652

643653
cfg_if! {
@@ -1020,6 +1030,33 @@ cfg_if! {
10201030
.finish()
10211031
}
10221032
}
1033+
1034+
impl Eq for ethhdr {}
1035+
1036+
impl PartialEq for ethhdr {
1037+
fn eq(&self, other: &ethhdr) -> bool {
1038+
self.h_dest
1039+
.iter()
1040+
.zip(other.h_dest.iter())
1041+
.all(|(a, b)| a == b)
1042+
&& self
1043+
.h_source
1044+
.iter()
1045+
.zip(other.h_source.iter())
1046+
.all(|(a, b)| a == b)
1047+
&& self.h_proto == other.h_proto
1048+
}
1049+
}
1050+
1051+
impl fmt::Debug for ethhdr {
1052+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1053+
f.debug_struct("ethhdr")
1054+
.field("h_dest", &self.h_dest)
1055+
.field("h_source", &self.h_source)
1056+
.field("h_proto", &{ self.h_proto })
1057+
.finish()
1058+
}
1059+
}
10231060
}
10241061
}
10251062

src/unix/linux_like/linux/gnu/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub type __rlimit_resource_t = c_uint;
77
pub type Lmid_t = c_long;
88
pub type regoff_t = c_int;
99
pub type __kernel_rwf_t = c_int;
10+
pub type __be16 = crate::__u16;
1011

1112
cfg_if! {
1213
if #[cfg(doc)] {
@@ -437,6 +438,15 @@ s_no_extra_traits! {
437438
__pad: [c_char; 4],
438439
__glibc_reserved: [c_char; 32],
439440
}
441+
442+
// linux/if_ether.h
443+
444+
#[repr(C, packed)]
445+
pub struct ethhdr {
446+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
447+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
448+
pub h_proto: crate::__be16,
449+
}
440450
}
441451

442452
// Internal, for casts to access union fields
@@ -646,6 +656,33 @@ cfg_if! {
646656
}
647657
}
648658
}
659+
660+
impl Eq for ethhdr {}
661+
662+
impl PartialEq for ethhdr {
663+
fn eq(&self, other: &ethhdr) -> bool {
664+
self.h_dest
665+
.iter()
666+
.zip(other.h_dest.iter())
667+
.all(|(a, b)| a == b)
668+
&& self
669+
.h_source
670+
.iter()
671+
.zip(other.h_source.iter())
672+
.all(|(a, b)| a == b)
673+
&& self.h_proto == other.h_proto
674+
}
675+
}
676+
677+
impl fmt::Debug for ethhdr {
678+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
679+
f.debug_struct("ethhdr")
680+
.field("h_dest", &self.h_dest)
681+
.field("h_source", &self.h_source)
682+
.field("h_proto", &{ self.h_proto })
683+
.finish()
684+
}
685+
}
649686
}
650687
}
651688

0 commit comments

Comments
 (0)