Skip to content

Commit b5ff627

Browse files
committed
freebsd add basic ethernet frames support
[reference](https://github.com/freebsd/freebsd-src/blob/stable/14/sys/net/ethernet.h)
1 parent 0f9f8c9 commit b5ff627

File tree

3 files changed

+103
-0
lines changed

3 files changed

+103
-0
lines changed

libc-test/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2197,6 +2197,7 @@ fn test_freebsd(target: &str) {
21972197
"memstat.h",
21982198
"mqueue.h",
21992199
"net/bpf.h",
2200+
"net/ethernet.h",
22002201
"net/if.h",
22012202
"net/if_arp.h",
22022203
"net/if_dl.h",

libc-test/semver/freebsd.txt

+13
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,17 @@ ERA_T_FMT
377377
EREMOTE
378378
ERPCMISMATCH
379379
ESOCKTNOSUPPORT
380+
ETHER_ADDR_LEN
381+
ETHER_CRC_LEN
382+
ETHER_HDR_LEN
383+
ETHER_IS_BROADCAST
384+
ETHER_IS_IPV6_MULTICAST
385+
ETHER_IS_MULTICAST
386+
ETHER_IS_ZERO
387+
ETHER_MIN_LEN
388+
ETHER_MAX_LEN
389+
ETHER_MAX_LEN_JUMBO
390+
ETHER_TYPE_LEN
380391
ETOOMANYREFS
381392
EUSERS
382393
EVFILT_AIO
@@ -1915,6 +1926,8 @@ endpwent
19151926
endservent
19161927
endutxent
19171928
erand48
1929+
ether_addr
1930+
ether_header
19181931
eui64_aton
19191932
eui64_hostton
19201933
eui64_ntoa

src/unix/bsd/freebsdlike/freebsd/mod.rs

+89
Original file line numberDiff line numberDiff line change
@@ -1661,6 +1661,18 @@ s_no_extra_traits! {
16611661
pub uc_flags: c_int,
16621662
__spare__: [c_int; 4],
16631663
}
1664+
1665+
#[repr(packed)]
1666+
pub struct ether_header {
1667+
pub ether_dhost: [crate::u_char; ETHER_ADDR_LEN as usize],
1668+
pub ether_shost: [crate::u_char; ETHER_ADDR_LEN as usize],
1669+
pub ether_type: crate::u_short,
1670+
}
1671+
1672+
#[repr(packed)]
1673+
pub struct ether_addr {
1674+
pub octet: [crate::u_char; ETHER_ADDR_LEN as usize],
1675+
}
16641676
}
16651677

16661678
cfg_if! {
@@ -2541,6 +2553,55 @@ cfg_if! {
25412553
.finish()
25422554
}
25432555
}
2556+
2557+
// FIXME(msrv): `derive` on packed structs cannot be used below 1.67
2558+
2559+
impl PartialEq for ether_header {
2560+
fn eq(&self, other: &ether_header) -> bool {
2561+
self.ether_dhost.iter().zip(other.ether_dhost.iter()).all(|(a, b)| a == b)
2562+
&& self.ether_dhost.iter().zip(other.ether_shost.iter()).all(|(a, b)| a == b)
2563+
&& self.ether_type == other.ether_type
2564+
}
2565+
}
2566+
2567+
impl Eq for ether_header {}
2568+
impl fmt::Debug for ether_header {
2569+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2570+
f.debug_struct("ether_header")
2571+
.field("ether_dhost", &{ self.ether_dhost })
2572+
.field("ether_shost", &{ self.ether_shost })
2573+
.field("ether_type", &{ self.ether_type })
2574+
.finish()
2575+
}
2576+
}
2577+
2578+
impl hash::Hash for ether_header {
2579+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
2580+
{ self.ether_dhost }.hash(state);
2581+
{ self.ether_shost }.hash(state);
2582+
{ self.ether_type }.hash(state);
2583+
}
2584+
}
2585+
2586+
impl PartialEq for ether_addr {
2587+
fn eq(&self, other: &ether_addr) -> bool {
2588+
self.octet.iter().zip(other.octet.iter()).all(|(a, b)| a == b)
2589+
}
2590+
}
2591+
2592+
impl Eq for ether_addr {}
2593+
impl fmt::Debug for ether_addr {
2594+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2595+
f.debug_struct("ether_addr")
2596+
.field("octet", &{ self.octet })
2597+
.finish()
2598+
}
2599+
}
2600+
impl hash::Hash for ether_header {
2601+
fn hash<H: hash::Hasher>(&self, state: &mut H) {
2602+
{ self.octet }.hash(state);
2603+
}
2604+
}
25442605
}
25452606
}
25462607

@@ -4647,6 +4708,16 @@ pub const RTM_VERSION: c_int = 5;
46474708

46484709
pub const RTAX_MAX: c_int = 8;
46494710

4711+
// net/ethernet.h
4712+
4713+
pub const ETHER_ADDR_LEN: c_int = 6;
4714+
pub const ETHER_TYPE_LEN: c_int = 2;
4715+
pub const ETHER_CRC_LEN: c_int = 4;
4716+
pub const ETHER_HDR_LEN: c_int = ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN;
4717+
pub const ETHER_MIN_LEN: c_int = 64;
4718+
pub const ETHER_MAX_LEN: c_int = 1518;
4719+
pub const ETHER_MAX_LEN_JUMBO: c_int = 9018;
4720+
46504721
// sys/signal.h
46514722
pub const SIGTHR: c_int = 32;
46524723
pub const SIGLWP: c_int = SIGTHR;
@@ -4957,6 +5028,24 @@ f! {
49575028
pub fn PROT_MAX_EXTRACT(x: c_int) -> c_int {
49585029
(x >> 16) & (crate::PROT_READ | crate::PROT_WRITE | crate::PROT_EXEC)
49595030
}
5031+
5032+
pub {const} fn ETHER_IS_MULTICAST(addr: *mut u_char) -> bool {
5033+
(*addr.wrapping_add(0)) & 0x01 != 0x00
5034+
}
5035+
5036+
pub {const} fn ETHER_IS_IPV6_MULTICAST(addr: *mut u_char) -> bool {
5037+
(*addr.wrapping_add(0)) == 0x33 && (*addr.wrapping_add(1)) == 0x33
5038+
}
5039+
5040+
pub {const} fn ETHER_IS_BROADCAST(addr: *mut u_char) -> bool {
5041+
(*addr.wrapping_add(0)) & (*addr.wrapping_add(1)) & (*addr.wrapping_add(2))
5042+
& (*addr.wrapping_add(3)) & (*addr.wrapping_add(4)) & (*addr.wrapping_add(5)) == 0xff
5043+
}
5044+
5045+
pub {const} fn ETHER_IS_ZERO(addr: *mut u_char) -> bool {
5046+
(*addr.wrapping_add(0)) | (*addr.wrapping_add(1)) | (*addr.wrapping_add(2))
5047+
| (*addr.wrapping_add(3)) | (*addr.wrapping_add(4)) | (*addr.wrapping_add(5)) == 0x00
5048+
}
49605049
}
49615050

49625051
safe_f! {

0 commit comments

Comments
 (0)