use crate::prelude_internal::*;
use core::fmt::{Debug, Formatter};
use num_derive::FromPrimitive;
use std::net::SocketAddrV6;
pub type Ip6Address = std::net::Ipv6Addr;
pub const IP6_PREFIX_BITSIZE: u8 = otsys::OT_IP6_PREFIX_BITSIZE as u8;
impl Transparent for std::net::Ipv6Addr {
fn from_ot(x: otIp6Address) -> std::net::Ipv6Addr {
unsafe { x.mFields.m8.into() }
}
fn into_ot(self) -> otIp6Address {
otIp6Address { mFields: otIp6Address__bindgen_ty_1 { m8: self.octets() } }
}
}
unsafe impl OtCastable for std::net::Ipv6Addr {
type OtType = otIp6Address;
fn as_ot_ptr(&self) -> *const otIp6Address {
sa::assert_eq_size!(Ip6Address, otIp6Address);
sa::assert_eq_align!(Ip6Address, otIp6Address);
self as *const Self as *const otIp6Address
}
fn as_ot_mut_ptr(&mut self) -> *mut Self::OtType {
self as *mut Self as *mut Self::OtType
}
unsafe fn ref_from_ot_ptr<'a>(ptr: *const otIp6Address) -> Option<&'a Self> {
if ptr.is_null() {
None
} else {
sa::assert_eq_size!(Ip6Address, otIp6Address);
sa::assert_eq_align!(Ip6Address, otIp6Address);
Some(&*(ptr as *const Self))
}
}
unsafe fn mut_from_ot_mut_ptr<'a>(ptr: *mut otIp6Address) -> Option<&'a mut Self> {
if ptr.is_null() {
None
} else {
sa::assert_eq_size!(Ip6Address, otIp6Address);
sa::assert_eq_align!(Ip6Address, otIp6Address);
Some(&mut *(ptr as *mut Self))
}
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct Ip6NetworkPrefix(pub otIp6NetworkPrefix);
impl_ot_castable!(Ip6NetworkPrefix, otIp6NetworkPrefix);
impl PartialEq for Ip6NetworkPrefix {
fn eq(&self, other: &Self) -> bool {
self.0.m8 == other.0.m8
}
}
impl Eq for Ip6NetworkPrefix {}
impl Debug for Ip6NetworkPrefix {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
std::net::Ipv6Addr::from(*self).fmt(f)?;
write!(f, "/64")
}
}
impl std::fmt::Display for Ip6NetworkPrefix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
impl Ip6NetworkPrefix {
pub fn as_slice(&self) -> &[u8] {
&self.0.m8
}
pub fn octets(&self) -> [u8; 8] {
let mut octets = [0u8; 8];
octets.clone_from_slice(self.as_slice());
octets
}
pub fn contains(&self, addr: &std::net::Ipv6Addr) -> bool {
self.0.m8 == addr.octets()[0..8]
}
}
impl From<[u8; 8]> for Ip6NetworkPrefix {
fn from(m8: [u8; 8]) -> Self {
Self(otIp6NetworkPrefix { m8 })
}
}
impl From<Ip6NetworkPrefix> for std::net::Ipv6Addr {
fn from(prefix: Ip6NetworkPrefix) -> Self {
let mut octets = [0u8; 16];
octets[0..8].clone_from_slice(prefix.as_slice());
octets.into()
}
}
impl From<std::net::Ipv6Addr> for Ip6NetworkPrefix {
fn from(x: std::net::Ipv6Addr) -> Self {
let mut ret = Ip6NetworkPrefix::default();
ret.0.m8.clone_from_slice(&x.octets()[0..8]);
ret
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct Ip6AddressInfo<'a>(otIp6AddressInfo, PhantomData<*mut &'a ()>);
impl_ot_castable!(lifetime Ip6AddressInfo<'_>, otIp6AddressInfo, Default::default());
impl Debug for Ip6AddressInfo<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.addr().fmt(f)?;
write!(f, "/{} {:?}", self.prefix_len(), self.scope())?;
if self.is_preferred() {
write!(f, " PREFERRED")?;
}
Ok(())
}
}
impl<'a> Ip6AddressInfo<'a> {
pub fn addr(&self) -> &'a Ip6Address {
unsafe { Ip6Address::ref_from_ot_ptr(self.0.mAddress).unwrap() }
}
pub fn is_preferred(&self) -> bool {
self.0.mPreferred()
}
pub fn prefix_len(&self) -> u8 {
self.0.mPrefixLength
}
pub fn scope(&self) -> Scope {
Scope(self.0.mScope())
}
pub fn is_multicast(&self) -> bool {
self.addr().is_multicast()
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
#[repr(transparent)]
pub struct Scope(pub u8);
#[allow(missing_docs)]
impl Scope {
pub const INTERFACE_LOCAL: Scope = Scope(0x1);
pub const LINK_LOCAL: Scope = Scope(0x2);
pub const REALM_LOCAL: Scope = Scope(0x3);
pub const ADMIN_LOCAL: Scope = Scope(0x4);
pub const SITE_LOCAL: Scope = Scope(0x5);
pub const ORGANIZATION_LOCAL: Scope = Scope(0x8);
pub const GLOBAL: Scope = Scope(0xe);
}
impl Debug for Scope {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match *self {
Self::INTERFACE_LOCAL => write!(f, "Scope::INTERFACE_LOCAL"),
Self::LINK_LOCAL => write!(f, "Scope::LINK_LOCAL"),
Self::REALM_LOCAL => write!(f, "Scope::REALM_LOCAL"),
Self::ADMIN_LOCAL => write!(f, "Scope::ADMIN_LOCAL"),
Self::SITE_LOCAL => write!(f, "Scope::SITE_LOCAL"),
Self::ORGANIZATION_LOCAL => write!(f, "Scope::ORGANIZATION_LOCAL"),
Self::GLOBAL => write!(f, "Scope::GLOBAL"),
Scope(x) => write!(f, "Scope({x})"),
}
}
}
impl From<Scope> for u8 {
fn from(x: Scope) -> Self {
x.0
}
}
impl From<Scope> for u32 {
fn from(x: Scope) -> Self {
x.0 as u32
}
}
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
pub struct AddressOrigin(pub u8);
impl AddressOrigin {
pub const DHCPV6: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_DHCPV6 as u8);
pub const MANUAL: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_MANUAL as u8);
pub const SLAAC: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_SLAAC as u8);
pub const THREAD: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_THREAD as u8);
}
impl Debug for AddressOrigin {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match *self {
Self::DHCPV6 => write!(f, "AddressOrigin::DHCPV6"),
Self::MANUAL => write!(f, "AddressOrigin::MANUAL"),
Self::SLAAC => write!(f, "AddressOrigin::SLAAC"),
Self::THREAD => write!(f, "AddressOrigin::THREAD"),
AddressOrigin(x) => write!(f, "AddressOrigin({x})"),
}
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct NetifAddress(pub(crate) otNetifAddress);
impl_ot_castable!(NetifAddress, otNetifAddress);
impl Debug for NetifAddress {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.addr().fmt(f)?;
write!(f, "/{} {:?}", self.prefix_len(), self.address_origin())?;
if let Some(scope) = self.scope() {
write!(f, " {scope:?}")?;
}
if self.is_valid() {
write!(f, " VALID")?;
}
if self.is_preferred() {
write!(f, " PREFERRED")?;
}
if self.is_rloc() {
write!(f, " RLOC")?;
}
Ok(())
}
}
impl std::fmt::Display for NetifAddress {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
impl NetifAddress {
pub fn new(addr: std::net::Ipv6Addr, prefix_len: u8) -> NetifAddress {
let mut ret = NetifAddress(otNetifAddress {
mAddress: addr.into_ot(),
mPrefixLength: prefix_len,
mAddressOrigin: 0,
_bitfield_align_1: [],
_bitfield_1: Default::default(),
mNext: std::ptr::null_mut(),
});
ret.set_valid(true);
ret.set_preferred(true);
ret
}
pub fn addr(&self) -> &Ip6Address {
Ip6Address::ref_from_ot_ref(&self.0.mAddress)
}
pub fn prefix_len(&self) -> u8 {
self.0.mPrefixLength
}
pub fn address_origin(&self) -> AddressOrigin {
AddressOrigin(self.0.mAddressOrigin)
}
pub fn scope(&self) -> Option<Scope> {
if self.0.mScopeOverrideValid() {
Some(Scope(self.0.mScopeOverride().try_into().expect("NetifAddress: invalid scope")))
} else {
None
}
}
pub fn set_scope(&mut self, scope: Option<Scope>) {
if let Some(scope) = scope {
self.0.set_mScopeOverrideValid(true);
self.0.set_mScopeOverride(scope.into());
} else {
self.0.set_mScopeOverrideValid(false);
}
}
pub fn is_preferred(&self) -> bool {
self.0.mPreferred()
}
pub fn set_preferred(&mut self, x: bool) {
self.0.set_mPreferred(x)
}
pub fn is_rloc(&self) -> bool {
self.0.mRloc()
}
pub fn set_rloc(&mut self, x: bool) {
self.0.set_mRloc(x)
}
pub fn is_valid(&self) -> bool {
self.0.mValid()
}
pub fn set_valid(&mut self, x: bool) {
self.0.set_mValid(x)
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct Ip6Prefix(pub otIp6Prefix);
impl_ot_castable!(Ip6Prefix, otIp6Prefix);
impl PartialEq for Ip6Prefix {
fn eq(&self, other: &Self) -> bool {
self.addr() == other.addr() && self.prefix_len() == other.prefix_len()
}
}
impl Eq for Ip6Prefix {}
impl Debug for Ip6Prefix {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.addr().fmt(f)?;
write!(f, "/{}", self.prefix_len())
}
}
impl std::fmt::Display for Ip6Prefix {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
impl Ip6Prefix {
pub fn new<T: Into<Ip6Address>>(addr: T, prefix_len: u8) -> Ip6Prefix {
Ip6Prefix(otIp6Prefix { mPrefix: addr.into().into_ot(), mLength: prefix_len })
}
pub fn addr(&self) -> &Ip6Address {
Ip6Address::ref_from_ot_ref(&self.0.mPrefix)
}
pub fn prefix_len(&self) -> u8 {
self.0.mLength
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct SockAddr(pub otSockAddr);
impl_ot_castable!(SockAddr, otSockAddr);
impl PartialEq for SockAddr {
fn eq(&self, other: &Self) -> bool {
self.addr() == other.addr() && self.port() == other.port()
}
}
impl Eq for SockAddr {}
impl Debug for SockAddr {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "[")?;
self.addr().fmt(f)?;
write!(f, "]:{}", self.port())
}
}
impl std::fmt::Display for SockAddr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
impl SockAddr {
pub fn new(addr: Ip6Address, port: u16) -> Self {
SockAddr(otSockAddr { mAddress: addr.into_ot(), mPort: port })
}
pub fn addr(&self) -> Ip6Address {
Ip6Address::from_ot(self.0.mAddress)
}
pub fn port(&self) -> u16 {
self.0.mPort
}
}
impl From<(Ip6Address, u16)> for SockAddr {
fn from(x: (Ip6Address, u16)) -> Self {
Self::new(x.0, x.1)
}
}
impl From<Ip6Address> for SockAddr {
fn from(x: Ip6Address) -> Self {
Self::new(x, 0)
}
}
impl From<std::net::SocketAddrV6> for SockAddr {
fn from(x: std::net::SocketAddrV6) -> Self {
SockAddr::new(*x.ip(), x.port())
}
}
impl From<SockAddr> for std::net::SocketAddrV6 {
fn from(x: SockAddr) -> Self {
SocketAddrV6::new(x.addr(), x.port(), 0, 0)
}
}
impl From<SockAddr> for std::net::SocketAddr {
fn from(x: SockAddr) -> Self {
std::net::SocketAddr::V6(x.into())
}
}
#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
#[allow(missing_docs)]
pub enum NetifIdentifier {
Backbone = OT_NETIF_BACKBONE as isize,
Thread = OT_NETIF_THREAD as isize,
Unspecified = OT_NETIF_UNSPECIFIED as isize,
}
impl From<otNetifIdentifier> for NetifIdentifier {
fn from(x: otNetifIdentifier) -> Self {
use num::FromPrimitive;
Self::from_u32(x).unwrap_or_else(|| panic!("Unknown otNetifIdentifier value: {x}"))
}
}
impl From<NetifIdentifier> for otNetifIdentifier {
fn from(x: NetifIdentifier) -> Self {
x as otNetifIdentifier
}
}
#[derive(Default, Clone, Copy)]
#[repr(transparent)]
pub struct BorderRoutingPrefixTableEntry(pub otBorderRoutingPrefixTableEntry);
impl_ot_castable!(BorderRoutingPrefixTableEntry, otBorderRoutingPrefixTableEntry);
impl Debug for BorderRoutingPrefixTableEntry {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_struct("otBorderRoutingPrefixTableEntry")
.field("router_address", &self.router_address())
.field("prefix", &self.prefix())
.field("is_on_link", &self.is_on_link())
.field("msec_since_last_update", &self.msec_since_last_update())
.field("valid_lifetime", &self.valid_lifetime())
.field("preferred_lifetime", &self.preferred_lifetime())
.field("route_preference", &self.route_preference())
.finish()
}
}
impl std::fmt::Display for BorderRoutingPrefixTableEntry {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Debug::fmt(self, f)
}
}
impl BorderRoutingPrefixTableEntry {
pub fn router_address(&self) -> &Ip6Address {
Ip6Address::ref_from_ot_ref(&self.0.mRouter.mAddress)
}
pub fn prefix(&self) -> &Ip6Prefix {
Ip6Prefix::ref_from_ot_ref(&self.0.mPrefix)
}
pub fn is_on_link(&self) -> bool {
self.0.mIsOnLink
}
pub fn msec_since_last_update(&self) -> u32 {
self.0.mMsecSinceLastUpdate
}
pub fn valid_lifetime(&self) -> u32 {
self.0.mValidLifetime
}
pub fn preferred_lifetime(&self) -> u32 {
self.0.mPreferredLifetime
}
pub fn route_preference(&self) -> RoutePreference {
RoutePreference::from_isize(self.0.mPreferredLifetime as isize)
.unwrap_or(RoutePreference::Medium)
}
}
#[derive(Debug, Default, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, FromPrimitive)]
#[allow(missing_docs)]
pub enum BorderRoutingDhcp6PdState {
#[default]
Disabled = OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED as isize,
Stopped = OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED as isize,
Running = OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING as isize,
}
impl From<otBorderRoutingDhcp6PdState> for BorderRoutingDhcp6PdState {
fn from(x: otBorderRoutingDhcp6PdState) -> Self {
use num::FromPrimitive;
Self::from_u32(x)
.unwrap_or_else(|| panic!("Unknown otBorderRoutingDhcp6PdState value: {x}"))
}
}
impl From<BorderRoutingDhcp6PdState> for otBorderRoutingDhcp6PdState {
fn from(x: BorderRoutingDhcp6PdState) -> Self {
x as otBorderRoutingDhcp6PdState
}
}