use zerocopy::FromBytes;
use crate::v1::definitions::AttributeType;
use crate::v1::parser::definitions::DataAttribute;
use crate::v1::parser::definitions::DataAttributeLong;
use crate::v1::parser::definitions::DataAttributeShort;
use crate::v1::parser::errors::IsakmpParseError;
pub fn parse_data_attribute(buf: &[u8]) -> Result<(DataAttribute, usize), IsakmpParseError> {
let first = buf.first().ok_or(IsakmpParseError::BufferTooSmall)? >> 7;
match first {
0 => {
let attribute = crate::v1::definitions::StaticDataAttributeLong::ref_from_prefix(buf)
.ok_or(IsakmpParseError::BufferTooSmall)?;
let da_size = size_of::<crate::v1::definitions::StaticDataAttributeLong>();
let attribute_size = da_size + attribute.attribute_length.get() as usize;
let attribute_value = buf
.get(da_size..attribute_size)
.ok_or(IsakmpParseError::BufferTooSmall)?
.to_vec();
Ok((
DataAttribute::DataAttributeLong(DataAttributeLong {
attribute_type: AttributeType::try_from(attribute.attribute_type.get())?,
attribute_value,
}),
attribute_size,
))
}
1 => {
let attribute = crate::v1::definitions::DataAttributeShort::ref_from_prefix(buf)
.ok_or(IsakmpParseError::BufferTooSmall)?;
Ok((
DataAttribute::DataAttributeShort(DataAttributeShort {
attribute_type: AttributeType::try_from(
attribute.attribute_type.get() & 0b0111_1111_1111_1111,
)?,
attribute_value: attribute.attribute_value.get(),
}),
size_of::<crate::v1::definitions::DataAttributeShort>(),
))
}
_ => unreachable!(),
}
}