use crate::ffi::scamper_icmpext::{self, ScamperIcmpextT, ScamperIcmpextsT};
pub struct ScamperIcmpExt {
inner: *mut ScamperIcmpextT,
}
impl ScamperIcmpExt {
pub(crate) unsafe fn from_ptr(ptr: *mut ScamperIcmpextT) -> Option<Self> {
if ptr.is_null() {
return None;
}
let ptr = unsafe { scamper_icmpext::scamper_icmpext_use(ptr) };
Some(ScamperIcmpExt { inner: ptr })
}
pub fn is_mpls(&self) -> bool {
unsafe { scamper_icmpext::scamper_icmpext_is_mpls(self.inner) != 0 }
}
pub fn mpls_count(&self) -> u16 {
unsafe { scamper_icmpext::scamper_icmpext_mpls_count_get(self.inner) }
}
pub fn mpls_label(&self, i: u16) -> u32 {
unsafe { scamper_icmpext::scamper_icmpext_mpls_label_get(self.inner, i) }
}
pub fn mpls_ttl(&self, i: u16) -> u8 {
unsafe { scamper_icmpext::scamper_icmpext_mpls_ttl_get(self.inner, i) }
}
pub fn mpls_exp(&self, i: u16) -> u8 {
unsafe { scamper_icmpext::scamper_icmpext_mpls_exp_get(self.inner, i) }
}
pub fn mpls_s(&self, i: u16) -> u8 {
unsafe { scamper_icmpext::scamper_icmpext_mpls_s_get(self.inner, i) }
}
pub fn mpls_labels(&self) -> MplsIter<'_> {
MplsIter { ext: self, index: 0, count: self.mpls_count() }
}
}
impl Drop for ScamperIcmpExt {
fn drop(&mut self) {
unsafe { scamper_icmpext::scamper_icmpext_free(self.inner) };
}
}
impl Clone for ScamperIcmpExt {
fn clone(&self) -> Self {
let ptr = unsafe { scamper_icmpext::scamper_icmpext_use(self.inner) };
ScamperIcmpExt { inner: ptr }
}
}
unsafe impl Send for ScamperIcmpExt {}
unsafe impl Sync for ScamperIcmpExt {}
#[derive(Debug, Clone, Copy)]
pub struct MplsLabel {
pub label: u32,
pub ttl: u8,
pub exp: u8,
pub s: u8,
}
pub struct MplsIter<'a> {
ext: &'a ScamperIcmpExt,
index: u16,
count: u16,
}
impl<'a> Iterator for MplsIter<'a> {
type Item = MplsLabel;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.count {
return None;
}
let i = self.index;
self.index += 1;
Some(MplsLabel {
label: self.ext.mpls_label(i),
ttl: self.ext.mpls_ttl(i),
exp: self.ext.mpls_exp(i),
s: self.ext.mpls_s(i),
})
}
}
pub struct ScamperIcmpExts {
inner: *mut ScamperIcmpextsT,
}
impl ScamperIcmpExts {
pub(crate) unsafe fn from_ptr(ptr: *mut ScamperIcmpextsT) -> Option<Self> {
if ptr.is_null() {
return None;
}
let ptr = unsafe { scamper_icmpext::scamper_icmpexts_use(ptr) };
Some(ScamperIcmpExts { inner: ptr })
}
pub fn count(&self) -> u16 {
unsafe { scamper_icmpext::scamper_icmpexts_count_get(self.inner) }
}
pub fn get(&self, i: u16) -> Option<ScamperIcmpExt> {
let ptr = unsafe { scamper_icmpext::scamper_icmpexts_ext_get(self.inner, i) };
unsafe { ScamperIcmpExt::from_ptr(ptr) }
}
pub fn iter(&self) -> IcmpExtsIter<'_> {
IcmpExtsIter { exts: self, index: 0, count: self.count() }
}
}
impl Drop for ScamperIcmpExts {
fn drop(&mut self) {
unsafe { scamper_icmpext::scamper_icmpexts_free(self.inner) };
}
}
impl Clone for ScamperIcmpExts {
fn clone(&self) -> Self {
let ptr = unsafe { scamper_icmpext::scamper_icmpexts_use(self.inner) };
ScamperIcmpExts { inner: ptr }
}
}
unsafe impl Send for ScamperIcmpExts {}
unsafe impl Sync for ScamperIcmpExts {}
pub struct IcmpExtsIter<'a> {
exts: &'a ScamperIcmpExts,
index: u16,
count: u16,
}
impl<'a> Iterator for IcmpExtsIter<'a> {
type Item = ScamperIcmpExt;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= self.count {
return None;
}
let i = self.index;
self.index += 1;
self.exts.get(i)
}
}