Skip to content

Commit 1fa2062

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 ec7da63 commit 1fa2062

File tree

5 files changed

+84
-0
lines changed

5 files changed

+84
-0
lines changed

libc-test/build.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2301,6 +2301,8 @@ fn test_android(target: &str) {
23012301
(struct_ == "sigaction" && field == "sa_sigaction") ||
23022302
// signalfd had SIGSYS fields added in Android 4.19, but CI does not have that version yet.
23032303
(struct_ == "signalfd_siginfo" && field == "ssi_call_addr") ||
2304+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
2305+
(struct_ == "ethhdr" && field == "h_proto") ||
23042306
// FIXME(android): Seems the type has been changed on NDK r26b
23052307
(struct_ == "flock64" && (field == "l_start" || field == "l_len"))
23062308
});
@@ -3918,6 +3920,10 @@ fn test_linux(target: &str) {
39183920
if sparc64 && (ty == "Elf32_Rela" || ty == "Elf64_Rela") {
39193921
return true;
39203922
}
3923+
// FIXME: alignment issue with this arch
3924+
if loongarch64 && ty == "ethhdr" {
3925+
return true;
3926+
}
39213927
match ty {
39223928
// FIXME(sighandler): `sighandler_t` type is incorrect, see:
39233929
// https://github.com/rust-lang/libc/issues/1359
@@ -4676,6 +4682,8 @@ fn test_linux(target: &str) {
46764682
(struct_ == "ptp_perout_request" && field == "anonymous_1") ||
46774683
// `anonymous_2` is an anonymous union
46784684
(struct_ == "ptp_perout_request" && field == "anonymous_2") ||
4685+
// FIXME: `h_proto` is of type __be16 big endian version of __u16
4686+
(struct_ == "ethhdr" && field == "h_proto") ||
46794687
// FIXME(linux): `adjust_phase` requires >= 5.7 kernel headers
46804688
// FIXME(linux): `max_phase_adj` requires >= 5.19 kernel headers
46814689
// 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
@@ -3277,6 +3277,7 @@ epoll_create1
32773277
epoll_ctl
32783278
epoll_event
32793279
epoll_wait
3280+
ethhdr
32803281
eventfd
32813282
eventfd_read
32823283
eventfd_write

libc-test/semver/linux-gnu.txt

+1
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,7 @@ dlmopen
590590
eaccess
591591
endutxent
592592
epoll_pwait2
593+
ethhdr
593594
euidaccess
594595
execveat
595596
explicit_bzero

src/unix/linux_like/android/mod.rs

+37
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

@@ -643,6 +644,15 @@ s_no_extra_traits! {
643644
pub ifc_len: c_int,
644645
pub ifc_ifcu: __c_anonymous_ifc_ifcu,
645646
}
647+
648+
// linux/if_ether.h
649+
650+
#[repr(C, packed)]
651+
pub struct ethhdr {
652+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
653+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
654+
pub h_proto: crate::__be16,
655+
}
646656
}
647657

648658
cfg_if! {
@@ -1025,6 +1035,33 @@ cfg_if! {
10251035
.finish()
10261036
}
10271037
}
1038+
1039+
impl Eq for ethhdr {}
1040+
1041+
impl PartialEq for ethhdr {
1042+
fn eq(&self, other: &ethhdr) -> bool {
1043+
self.h_dest
1044+
.iter()
1045+
.zip(other.h_dest.iter())
1046+
.all(|(a, b)| a == b)
1047+
&& self
1048+
.h_source
1049+
.iter()
1050+
.zip(other.h_source.iter())
1051+
.all(|(a, b)| a == b)
1052+
&& self.h_proto == other.h_proto
1053+
}
1054+
}
1055+
1056+
impl fmt::Debug for ethhdr {
1057+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1058+
f.debug_struct("ethhdr")
1059+
.field("h_dest", &self.h_dest)
1060+
.field("h_source", &self.h_source)
1061+
.field("h_proto", &{ self.h_proto })
1062+
.finish()
1063+
}
1064+
}
10281065
}
10291066
}
10301067

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

+37
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)] {
@@ -466,6 +467,15 @@ s_no_extra_traits! {
466467
__pad: [c_char; 4],
467468
__glibc_reserved: [c_char; 32],
468469
}
470+
471+
// linux/if_ether.h
472+
473+
#[repr(C, packed)]
474+
pub struct ethhdr {
475+
pub h_dest: [c_uchar; crate::ETH_ALEN as usize],
476+
pub h_source: [c_uchar; crate::ETH_ALEN as usize],
477+
pub h_proto: crate::__be16,
478+
}
469479
}
470480

471481
// Internal, for casts to access union fields
@@ -675,6 +685,33 @@ cfg_if! {
675685
}
676686
}
677687
}
688+
689+
impl Eq for ethhdr {}
690+
691+
impl PartialEq for ethhdr {
692+
fn eq(&self, other: &ethhdr) -> bool {
693+
self.h_dest
694+
.iter()
695+
.zip(other.h_dest.iter())
696+
.all(|(a, b)| a == b)
697+
&& self
698+
.h_source
699+
.iter()
700+
.zip(other.h_source.iter())
701+
.all(|(a, b)| a == b)
702+
&& self.h_proto == other.h_proto
703+
}
704+
}
705+
706+
impl fmt::Debug for ethhdr {
707+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
708+
f.debug_struct("ethhdr")
709+
.field("h_dest", &self.h_dest)
710+
.field("h_source", &self.h_source)
711+
.field("h_proto", &{ self.h_proto })
712+
.finish()
713+
}
714+
}
678715
}
679716
}
680717

0 commit comments

Comments
 (0)