use super::header::*;
use crate::{DecodeError, Field, Index, NlaBuffer, NlasIterator, Rest};
use byteorder::{ByteOrder, NativeEndian};
const ADDRESS_FAMILY: Index = 0;
const DEST_LENGTH: Index = 1;
const SOURCE_LENGTH: Index = 2;
const TOS: Index = 3;
const TABLE_ID: Index = 4;
const ROUTING_PROTOCOL: Index = 5;
const SCOPE: Index = 6;
const TYPE: Index = 7;
const FLAGS: Field = 8..12;
const ATTRIBUTES: Rest = 12..;
pub const ROUTE_HEADER_LEN: usize = ATTRIBUTES.start;
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct RouteBuffer<T> {
buffer: T,
}
impl<T: AsRef<[u8]>> RouteBuffer<T> {
pub fn new(buffer: T) -> RouteBuffer<T> {
RouteBuffer { buffer }
}
pub fn into_inner(self) -> T {
self.buffer
}
pub fn address_family(&self) -> u8 {
let data = self.buffer.as_ref();
data[ADDRESS_FAMILY]
}
pub fn destination_length(&self) -> u8 {
let data = self.buffer.as_ref();
data[DEST_LENGTH]
}
pub fn source_length(&self) -> u8 {
let data = self.buffer.as_ref();
data[SOURCE_LENGTH]
}
pub fn tos(&self) -> u8 {
let data = self.buffer.as_ref();
data[TOS]
}
pub fn table(&self) -> RouteTable {
let data = self.buffer.as_ref();
data[TABLE_ID].into()
}
pub fn protocol(&self) -> RouteProtocol {
let data = self.buffer.as_ref();
data[ROUTING_PROTOCOL].into()
}
pub fn scope(&self) -> RouteScope {
let data = self.buffer.as_ref();
data[SCOPE].into()
}
pub fn kind(&self) -> RouteKind {
let data = self.buffer.as_ref();
data[TYPE].into()
}
pub fn flags(&self) -> RouteFlags {
let data = self.buffer.as_ref();
NativeEndian::read_u32(&data[FLAGS]).into()
}
}
impl<'a, T: AsRef<[u8]> + ?Sized> RouteBuffer<&'a T> {
pub fn payload(&self) -> &'a [u8] {
let data = self.buffer.as_ref();
&data[ATTRIBUTES]
}
pub fn nlas(&self) -> impl Iterator<Item = Result<NlaBuffer<&'a [u8]>, DecodeError>> {
NlasIterator::new(self.payload())
}
}
impl<'a, T: AsRef<[u8]> + AsMut<[u8]> + ?Sized> RouteBuffer<&'a mut T> {
pub fn payload_mut(&mut self) -> &mut [u8] {
let data = self.buffer.as_mut();
&mut data[ATTRIBUTES]
}
}
impl<T: AsRef<[u8]> + AsMut<[u8]>> RouteBuffer<T> {
pub fn set_address_family(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[ADDRESS_FAMILY] = value
}
pub fn set_destination_length(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[DEST_LENGTH] = value
}
pub fn set_source_length(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[SOURCE_LENGTH] = value
}
pub fn set_tos(&mut self, value: u8) {
let data = self.buffer.as_mut();
data[TOS] = value
}
pub fn set_table(&mut self, value: RouteTable) {
let data = self.buffer.as_mut();
data[TABLE_ID] = value.into()
}
pub fn set_protocol(&mut self, value: RouteProtocol) {
let data = self.buffer.as_mut();
data[ROUTING_PROTOCOL] = value.into()
}
pub fn set_scope(&mut self, value: RouteScope) {
let data = self.buffer.as_mut();
data[SCOPE] = value.into()
}
pub fn set_kind(&mut self, value: RouteKind) {
let data = self.buffer.as_mut();
data[TYPE] = value.into()
}
pub fn set_flags(&mut self, value: RouteFlags) {
let data = self.buffer.as_mut();
NativeEndian::write_u32(&mut data[FLAGS], value.into())
}
}