1use crate::prelude_internal::*;
6
7use core::fmt::{Debug, Formatter};
8use num_derive::FromPrimitive;
9use std::net::SocketAddrV6;
10
11pub type Ip6Address = std::net::Ipv6Addr;
31
32pub const IP6_PREFIX_BITSIZE: u8 = otsys::OT_IP6_PREFIX_BITSIZE as u8;
34
35impl Transparent for std::net::Ipv6Addr {
36 fn from_ot(x: otIp6Address) -> std::net::Ipv6Addr {
37 unsafe { x.mFields.m8.into() }
38 }
39
40 fn into_ot(self) -> otIp6Address {
41 otIp6Address { mFields: otIp6Address__bindgen_ty_1 { m8: self.octets() } }
42 }
43}
44
45unsafe impl OtCastable for std::net::Ipv6Addr {
46 type OtType = otIp6Address;
47
48 fn as_ot_ptr(&self) -> *const otIp6Address {
49 sa::assert_eq_size!(Ip6Address, otIp6Address);
50 sa::assert_eq_align!(Ip6Address, otIp6Address);
51 self as *const Self as *const otIp6Address
52 }
53
54 fn as_ot_mut_ptr(&mut self) -> *mut Self::OtType {
55 self as *mut Self as *mut Self::OtType
56 }
57
58 unsafe fn ref_from_ot_ptr<'a>(ptr: *const otIp6Address) -> Option<&'a Self> {
59 if ptr.is_null() {
60 None
61 } else {
62 sa::assert_eq_size!(Ip6Address, otIp6Address);
63 sa::assert_eq_align!(Ip6Address, otIp6Address);
64
65 Some(unsafe { &*(ptr as *const Self) })
67 }
68 }
69
70 unsafe fn mut_from_ot_mut_ptr<'a>(ptr: *mut otIp6Address) -> Option<&'a mut Self> {
71 if ptr.is_null() {
72 None
73 } else {
74 sa::assert_eq_size!(Ip6Address, otIp6Address);
75 sa::assert_eq_align!(Ip6Address, otIp6Address);
76
77 Some(unsafe { &mut *(ptr as *mut Self) })
79 }
80 }
81}
82
83#[derive(Default, Clone, Copy)]
87#[repr(transparent)]
88pub struct Ip6NetworkPrefix(pub otIp6NetworkPrefix);
89
90impl_ot_castable!(Ip6NetworkPrefix, otIp6NetworkPrefix);
91
92impl PartialEq for Ip6NetworkPrefix {
93 fn eq(&self, other: &Self) -> bool {
94 self.0.m8 == other.0.m8
95 }
96}
97
98impl Eq for Ip6NetworkPrefix {}
99
100impl Debug for Ip6NetworkPrefix {
101 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
102 std::net::Ipv6Addr::from(*self).fmt(f)?;
103 write!(f, "/64")
104 }
105}
106
107impl std::fmt::Display for Ip6NetworkPrefix {
108 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
109 std::fmt::Debug::fmt(self, f)
110 }
111}
112
113impl Ip6NetworkPrefix {
114 pub fn as_slice(&self) -> &[u8] {
116 &self.0.m8
117 }
118
119 pub fn octets(&self) -> [u8; 8] {
121 let mut octets = [0u8; 8];
122 octets.clone_from_slice(self.as_slice());
123 octets
124 }
125
126 pub fn contains(&self, addr: &std::net::Ipv6Addr) -> bool {
128 self.0.m8 == addr.octets()[0..8]
129 }
130
131 pub fn get_scope(&self) -> Scope {
133 let addr: std::net::Ipv6Addr = (*self).into();
134 if addr.is_multicast() {
135 ot::types::ipv6::Scope::from(addr.octets()[1] & 0xf)
136 } else if self.is_link_local() {
137 Scope::LINK_LOCAL
138 } else if addr.is_loopback() {
139 Scope::NODE_LOCAL
140 } else {
141 Scope::GLOBAL
142 }
143 }
144
145 pub fn is_link_local(&self) -> bool {
147 (self.0.m8[0] == 0xfe) && ((self.0.m8[1] & 0xc0) == 0x80)
148 }
149}
150
151impl From<[u8; 8]> for Ip6NetworkPrefix {
152 fn from(m8: [u8; 8]) -> Self {
153 Self(otIp6NetworkPrefix { m8 })
154 }
155}
156
157impl From<Ip6NetworkPrefix> for std::net::Ipv6Addr {
158 fn from(prefix: Ip6NetworkPrefix) -> Self {
159 let mut octets = [0u8; 16];
160 octets[0..8].clone_from_slice(prefix.as_slice());
161 octets.into()
162 }
163}
164
165impl From<std::net::Ipv6Addr> for Ip6NetworkPrefix {
166 fn from(x: std::net::Ipv6Addr) -> Self {
167 let mut ret = Ip6NetworkPrefix::default();
168 ret.0.m8.clone_from_slice(&x.octets()[0..8]);
169 ret
170 }
171}
172
173#[derive(Default, Clone, Copy)]
179#[repr(transparent)]
180pub struct Ip6AddressInfo<'a>(otIp6AddressInfo, PhantomData<*mut &'a ()>);
181
182impl_ot_castable!(lifetime Ip6AddressInfo<'_>, otIp6AddressInfo, Default::default());
183
184impl Debug for Ip6AddressInfo<'_> {
185 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
186 self.addr().fmt(f)?;
187 write!(f, "/{} {:?}", self.prefix_len(), self.scope())?;
188 if self.is_preferred() {
189 write!(f, " PREFERRED")?;
190 }
191
192 Ok(())
193 }
194}
195
196impl<'a> Ip6AddressInfo<'a> {
197 pub fn addr(&self) -> &'a Ip6Address {
199 unsafe { Ip6Address::ref_from_ot_ptr(self.0.mAddress).unwrap() }
200 }
201
202 pub fn is_preferred(&self) -> bool {
204 self.0.mPreferred()
205 }
206
207 pub fn prefix_len(&self) -> u8 {
209 self.0.mPrefixLength
210 }
211
212 pub fn scope(&self) -> Scope {
214 Scope(self.0.mScope())
215 }
216
217 pub fn is_multicast(&self) -> bool {
219 self.addr().is_multicast()
220 }
221}
222
223#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
225#[repr(transparent)]
226pub struct Scope(pub u8);
227
228#[allow(missing_docs)]
229impl Scope {
230 pub const NODE_LOCAL: Scope = Scope(0x0);
231 pub const INTERFACE_LOCAL: Scope = Scope(0x1);
232 pub const LINK_LOCAL: Scope = Scope(0x2);
233 pub const REALM_LOCAL: Scope = Scope(0x3);
234 pub const ADMIN_LOCAL: Scope = Scope(0x4);
235 pub const SITE_LOCAL: Scope = Scope(0x5);
236 pub const ORGANIZATION_LOCAL: Scope = Scope(0x8);
237 pub const GLOBAL: Scope = Scope(0xe);
238}
239
240impl Debug for Scope {
241 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
242 match *self {
243 Self::INTERFACE_LOCAL => write!(f, "Scope::INTERFACE_LOCAL"),
244 Self::LINK_LOCAL => write!(f, "Scope::LINK_LOCAL"),
245 Self::REALM_LOCAL => write!(f, "Scope::REALM_LOCAL"),
246 Self::ADMIN_LOCAL => write!(f, "Scope::ADMIN_LOCAL"),
247 Self::SITE_LOCAL => write!(f, "Scope::SITE_LOCAL"),
248 Self::ORGANIZATION_LOCAL => write!(f, "Scope::ORGANIZATION_LOCAL"),
249 Self::GLOBAL => write!(f, "Scope::GLOBAL"),
250 Scope(x) => write!(f, "Scope({x})"),
251 }
252 }
253}
254
255impl From<Scope> for u8 {
256 fn from(x: Scope) -> Self {
257 x.0
258 }
259}
260
261impl From<u8> for Scope {
262 fn from(x: u8) -> Self {
263 Scope(x)
264 }
265}
266
267impl From<Scope> for u32 {
268 fn from(x: Scope) -> Self {
269 x.0 as u32
270 }
271}
272
273#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
275pub struct AddressOrigin(pub u8);
276
277impl AddressOrigin {
278 pub const DHCPV6: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_DHCPV6 as u8);
281
282 pub const MANUAL: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_MANUAL as u8);
285
286 pub const SLAAC: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_SLAAC as u8);
289
290 pub const THREAD: AddressOrigin = AddressOrigin(OT_ADDRESS_ORIGIN_THREAD as u8);
293}
294
295impl Debug for AddressOrigin {
296 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
297 match *self {
298 Self::DHCPV6 => write!(f, "AddressOrigin::DHCPV6"),
299 Self::MANUAL => write!(f, "AddressOrigin::MANUAL"),
300 Self::SLAAC => write!(f, "AddressOrigin::SLAAC"),
301 Self::THREAD => write!(f, "AddressOrigin::THREAD"),
302 AddressOrigin(x) => write!(f, "AddressOrigin({x})"),
303 }
304 }
305}
306
307#[derive(Default, Clone, Copy)]
310#[repr(transparent)]
311pub struct NetifAddress(pub(crate) otNetifAddress);
312
313impl_ot_castable!(NetifAddress, otNetifAddress);
314
315impl Debug for NetifAddress {
316 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
317 self.addr().fmt(f)?;
318 write!(f, "/{} {:?}", self.prefix_len(), self.address_origin())?;
319 if let Some(scope) = self.scope() {
320 write!(f, " {scope:?}")?;
321 }
322 if self.is_valid() {
323 write!(f, " VALID")?;
324 }
325 if self.is_preferred() {
326 write!(f, " PREFERRED")?;
327 }
328 if self.is_rloc() {
329 write!(f, " RLOC")?;
330 }
331 Ok(())
332 }
333}
334
335impl std::fmt::Display for NetifAddress {
336 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
337 std::fmt::Debug::fmt(self, f)
338 }
339}
340
341impl NetifAddress {
342 pub fn new(addr: std::net::Ipv6Addr, prefix_len: u8) -> NetifAddress {
346 let mut ret = NetifAddress(otNetifAddress {
347 mAddress: addr.into_ot(),
348 mPrefixLength: prefix_len,
349 mAddressOrigin: 0,
350 _bitfield_align_1: [],
351 _bitfield_1: Default::default(),
352 mNext: std::ptr::null_mut(),
353 });
354 ret.set_valid(true);
355 ret.set_preferred(true);
356 ret
357 }
358
359 pub fn addr(&self) -> &Ip6Address {
361 Ip6Address::ref_from_ot_ref(&self.0.mAddress)
362 }
363
364 pub fn prefix_len(&self) -> u8 {
366 self.0.mPrefixLength
367 }
368
369 pub fn address_origin(&self) -> AddressOrigin {
371 AddressOrigin(self.0.mAddressOrigin)
372 }
373
374 pub fn scope(&self) -> Option<Scope> {
376 if self.0.mScopeOverrideValid() {
377 Some(Scope(self.0.mScopeOverride().try_into().expect("NetifAddress: invalid scope")))
378 } else {
379 None
380 }
381 }
382
383 pub fn set_scope(&mut self, scope: Option<Scope>) {
385 if let Some(scope) = scope {
386 self.0.set_mScopeOverrideValid(true);
387 self.0.set_mScopeOverride(scope.into());
388 } else {
389 self.0.set_mScopeOverrideValid(false);
390 }
391 }
392
393 pub fn is_preferred(&self) -> bool {
395 self.0.mPreferred()
396 }
397
398 pub fn set_preferred(&mut self, x: bool) {
400 self.0.set_mPreferred(x)
401 }
402
403 pub fn is_rloc(&self) -> bool {
405 self.0.mRloc()
406 }
407
408 pub fn set_rloc(&mut self, x: bool) {
410 self.0.set_mRloc(x)
411 }
412
413 pub fn is_valid(&self) -> bool {
415 self.0.mValid()
416 }
417
418 pub fn set_valid(&mut self, x: bool) {
420 self.0.set_mValid(x)
421 }
422}
423
424#[derive(Default, Clone, Copy)]
427#[repr(transparent)]
428pub struct Ip6Prefix(pub otIp6Prefix);
429
430impl_ot_castable!(Ip6Prefix, otIp6Prefix);
431
432impl PartialEq for Ip6Prefix {
433 fn eq(&self, other: &Self) -> bool {
434 self.addr() == other.addr() && self.prefix_len() == other.prefix_len()
435 }
436}
437
438impl Eq for Ip6Prefix {}
439
440impl Debug for Ip6Prefix {
441 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
442 self.addr().fmt(f)?;
443 write!(f, "/{}", self.prefix_len())
444 }
445}
446
447impl std::fmt::Display for Ip6Prefix {
448 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
449 std::fmt::Debug::fmt(self, f)
450 }
451}
452
453impl Ip6Prefix {
454 pub fn new<T: Into<Ip6Address>>(addr: T, prefix_len: u8) -> Ip6Prefix {
456 Ip6Prefix(otIp6Prefix { mPrefix: addr.into().into_ot(), mLength: prefix_len })
457 }
458
459 pub fn addr(&self) -> &Ip6Address {
461 Ip6Address::ref_from_ot_ref(&self.0.mPrefix)
462 }
463
464 pub fn prefix_len(&self) -> u8 {
466 self.0.mLength
467 }
468}
469
470#[derive(Default, Clone, Copy)]
472#[repr(transparent)]
473pub struct SockAddr(pub otSockAddr);
474
475impl_ot_castable!(SockAddr, otSockAddr);
476
477impl PartialEq for SockAddr {
478 fn eq(&self, other: &Self) -> bool {
479 self.addr() == other.addr() && self.port() == other.port()
480 }
481}
482
483impl Eq for SockAddr {}
484
485impl Debug for SockAddr {
486 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
487 write!(f, "[")?;
488 self.addr().fmt(f)?;
489 write!(f, "]:{}", self.port())
490 }
491}
492
493impl std::fmt::Display for SockAddr {
494 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
495 std::fmt::Debug::fmt(self, f)
496 }
497}
498
499impl SockAddr {
500 pub fn new(addr: Ip6Address, port: u16) -> Self {
502 SockAddr(otSockAddr { mAddress: addr.into_ot(), mPort: port })
503 }
504
505 pub fn addr(&self) -> Ip6Address {
507 Ip6Address::from_ot(self.0.mAddress)
508 }
509
510 pub fn port(&self) -> u16 {
512 self.0.mPort
513 }
514}
515
516impl From<(Ip6Address, u16)> for SockAddr {
517 fn from(x: (Ip6Address, u16)) -> Self {
518 Self::new(x.0, x.1)
519 }
520}
521
522impl From<Ip6Address> for SockAddr {
523 fn from(x: Ip6Address) -> Self {
524 Self::new(x, 0)
525 }
526}
527
528impl From<std::net::SocketAddrV6> for SockAddr {
529 fn from(x: std::net::SocketAddrV6) -> Self {
530 SockAddr::new(*x.ip(), x.port())
531 }
532}
533
534impl From<SockAddr> for std::net::SocketAddrV6 {
535 fn from(x: SockAddr) -> Self {
536 SocketAddrV6::new(x.addr(), x.port(), 0, 0)
537 }
538}
539
540impl From<SockAddr> for std::net::SocketAddr {
541 fn from(x: SockAddr) -> Self {
542 std::net::SocketAddr::V6(x.into())
543 }
544}
545
546#[derive(Debug, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, num_derive::FromPrimitive)]
550#[allow(missing_docs)]
551pub enum NetifIdentifier {
552 Backbone = OT_NETIF_BACKBONE as isize,
554
555 Thread = OT_NETIF_THREAD_HOST as isize,
557
558 Unspecified = OT_NETIF_UNSPECIFIED as isize,
560}
561
562impl From<otNetifIdentifier> for NetifIdentifier {
563 fn from(x: otNetifIdentifier) -> Self {
564 use num::FromPrimitive;
565 Self::from_u32(x).unwrap_or_else(|| panic!("Unknown otNetifIdentifier value: {x}"))
566 }
567}
568
569impl From<NetifIdentifier> for otNetifIdentifier {
570 fn from(x: NetifIdentifier) -> Self {
571 x as otNetifIdentifier
572 }
573}
574
575#[derive(Default, Clone, Copy)]
578#[repr(transparent)]
579pub struct BorderRoutingPrefixTableEntry(pub otBorderRoutingPrefixTableEntry);
580
581impl_ot_castable!(BorderRoutingPrefixTableEntry, otBorderRoutingPrefixTableEntry);
582
583impl Debug for BorderRoutingPrefixTableEntry {
584 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
585 f.debug_struct("otBorderRoutingPrefixTableEntry")
586 .field("router_address", &self.router_address())
587 .field("prefix", &self.prefix())
588 .field("is_on_link", &self.is_on_link())
589 .field("msec_since_last_update", &self.msec_since_last_update())
590 .field("valid_lifetime", &self.valid_lifetime())
591 .field("preferred_lifetime", &self.preferred_lifetime())
592 .field("route_preference", &self.route_preference())
593 .finish()
594 }
595}
596
597impl std::fmt::Display for BorderRoutingPrefixTableEntry {
598 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
599 std::fmt::Debug::fmt(self, f)
600 }
601}
602
603impl BorderRoutingPrefixTableEntry {
604 pub fn router_address(&self) -> &Ip6Address {
606 Ip6Address::ref_from_ot_ref(&self.0.mRouter.mAddress)
607 }
608
609 pub fn prefix(&self) -> &Ip6Prefix {
611 Ip6Prefix::ref_from_ot_ref(&self.0.mPrefix)
612 }
613
614 pub fn is_on_link(&self) -> bool {
616 self.0.mIsOnLink
617 }
618
619 pub fn msec_since_last_update(&self) -> u32 {
621 self.0.mMsecSinceLastUpdate
622 }
623
624 pub fn valid_lifetime(&self) -> u32 {
626 self.0.mValidLifetime
627 }
628
629 pub fn preferred_lifetime(&self) -> u32 {
631 self.0.mPreferredLifetime
632 }
633
634 pub fn route_preference(&self) -> RoutePreference {
636 RoutePreference::from_isize(self.0.mPreferredLifetime as isize)
637 .unwrap_or(RoutePreference::Medium)
638 }
639}
640
641#[derive(Debug, Default, Copy, Clone, Eq, Ord, PartialOrd, PartialEq, FromPrimitive)]
645#[allow(missing_docs)]
646pub enum BorderRoutingDhcp6PdState {
647 #[default]
648 Disabled = OT_BORDER_ROUTING_DHCP6_PD_STATE_DISABLED as isize,
650
651 Stopped = OT_BORDER_ROUTING_DHCP6_PD_STATE_STOPPED as isize,
653
654 Running = OT_BORDER_ROUTING_DHCP6_PD_STATE_RUNNING as isize,
656
657 Idle = OT_BORDER_ROUTING_DHCP6_PD_STATE_IDLE as isize,
659}
660
661impl From<otBorderRoutingDhcp6PdState> for BorderRoutingDhcp6PdState {
662 fn from(x: otBorderRoutingDhcp6PdState) -> Self {
663 use num::FromPrimitive;
664 Self::from_u32(x)
665 .unwrap_or_else(|| panic!("Unknown otBorderRoutingDhcp6PdState value: {x}"))
666 }
667}
668
669impl From<BorderRoutingDhcp6PdState> for otBorderRoutingDhcp6PdState {
670 fn from(x: BorderRoutingDhcp6PdState) -> Self {
671 x as otBorderRoutingDhcp6PdState
672 }
673}