Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

freebsd add basic ethernet frames support #4252

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libc-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2197,6 +2197,7 @@ fn test_freebsd(target: &str) {
"memstat.h",
"mqueue.h",
"net/bpf.h",
"net/ethernet.h",
"net/if.h",
"net/if_arp.h",
"net/if_dl.h",
Expand Down
13 changes: 13 additions & 0 deletions libc-test/semver/freebsd.txt
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,17 @@ ERA_T_FMT
EREMOTE
ERPCMISMATCH
ESOCKTNOSUPPORT
ETHER_ADDR_LEN
ETHER_CRC_LEN
ETHER_HDR_LEN
ETHER_IS_BROADCAST
ETHER_IS_IPV6_MULTICAST
ETHER_IS_MULTICAST
ETHER_IS_ZERO
ETHER_MIN_LEN
ETHER_MAX_LEN
ETHER_MAX_LEN_JUMBO
ETHER_TYPE_LEN
ETOOMANYREFS
EUSERS
EVFILT_AIO
Expand Down Expand Up @@ -1915,6 +1926,8 @@ endpwent
endservent
endutxent
erand48
ether_addr
ether_header
eui64_aton
eui64_hostton
eui64_ntoa
Expand Down
89 changes: 89 additions & 0 deletions src/unix/bsd/freebsdlike/freebsd/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,18 @@ s_no_extra_traits! {
pub uc_flags: c_int,
__spare__: [c_int; 4],
}

#[repr(packed)]
pub struct ether_header {
pub ether_dhost: [crate::u_char; ETHER_ADDR_LEN as usize],
pub ether_shost: [crate::u_char; ETHER_ADDR_LEN as usize],
pub ether_type: crate::u_short,
}

#[repr(packed)]
pub struct ether_addr {
pub octet: [crate::u_char; ETHER_ADDR_LEN as usize],
}
}

cfg_if! {
Expand Down Expand Up @@ -2541,6 +2553,55 @@ cfg_if! {
.finish()
}
}

tgross35 marked this conversation as resolved.
Show resolved Hide resolved
// FIXME(msrv): `derive` on packed structs cannot be used below 1.67
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds to me like a compelling reason to raise the main branch's MSRV. Why is it currently set to 1.63?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1.63 is what Debian stable currently ships so it is a pretty common baseline in the ecosystem. In a few months Trixie will be released 1.83 (or higher) so we will probably be able to do another bump (not that high, but at least above 1.63).


impl PartialEq for ether_header {
fn eq(&self, other: &ether_header) -> bool {
self.ether_dhost.iter().zip(other.ether_dhost.iter()).all(|(a, b)| a == b)
&& self.ether_dhost.iter().zip(other.ether_shost.iter()).all(|(a, b)| a == b)
&& self.ether_type == other.ether_type
}
}

impl Eq for ether_header {}
impl fmt::Debug for ether_header {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ether_header")
.field("ether_dhost", &{ self.ether_dhost })
.field("ether_shost", &{ self.ether_shost })
.field("ether_type", &{ self.ether_type })
.finish()
}
}

impl hash::Hash for ether_header {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
{ self.ether_dhost }.hash(state);
{ self.ether_shost }.hash(state);
{ self.ether_type }.hash(state);
}
}

impl PartialEq for ether_addr {
fn eq(&self, other: &ether_addr) -> bool {
self.octet.iter().zip(other.octet.iter()).all(|(a, b)| a == b)
}
}

impl Eq for ether_addr {}
impl fmt::Debug for ether_addr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("ether_addr")
.field("octet", &{ self.octet })
.finish()
}
}
impl hash::Hash for ether_header {
fn hash<H: hash::Hasher>(&self, state: &mut H) {
{ self.octet }.hash(state);
}
}
}
}

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

pub const RTAX_MAX: c_int = 8;

// net/ethernet.h

pub const ETHER_ADDR_LEN: c_int = 6;
pub const ETHER_TYPE_LEN: c_int = 2;
pub const ETHER_CRC_LEN: c_int = 4;
pub const ETHER_HDR_LEN: c_int = ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN;
pub const ETHER_MIN_LEN: c_int = 64;
pub const ETHER_MAX_LEN: c_int = 1518;
pub const ETHER_MAX_LEN_JUMBO: c_int = 9018;

// sys/signal.h
pub const SIGTHR: c_int = 32;
pub const SIGLWP: c_int = SIGTHR;
Expand Down Expand Up @@ -4957,6 +5028,24 @@ f! {
pub fn PROT_MAX_EXTRACT(x: c_int) -> c_int {
(x >> 16) & (crate::PROT_READ | crate::PROT_WRITE | crate::PROT_EXEC)
}

pub {const} fn ETHER_IS_MULTICAST(addr: *mut u_char) -> bool {
(*addr.wrapping_add(0)) & 0x01 != 0x00
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised that Clippy doesn't complain about the uselessness of wrapping_add(0).

}

pub {const} fn ETHER_IS_IPV6_MULTICAST(addr: *mut u_char) -> bool {
(*addr.wrapping_add(0)) == 0x33 && (*addr.wrapping_add(1)) == 0x33
}

pub {const} fn ETHER_IS_BROADCAST(addr: *mut u_char) -> bool {
(*addr.wrapping_add(0)) & (*addr.wrapping_add(1)) & (*addr.wrapping_add(2))
& (*addr.wrapping_add(3)) & (*addr.wrapping_add(4)) & (*addr.wrapping_add(5)) == 0xff
}

pub {const} fn ETHER_IS_ZERO(addr: *mut u_char) -> bool {
(*addr.wrapping_add(0)) | (*addr.wrapping_add(1)) | (*addr.wrapping_add(2))
| (*addr.wrapping_add(3)) | (*addr.wrapping_add(4)) | (*addr.wrapping_add(5)) == 0x00
}
}

safe_f! {
Expand Down
Loading