use bytes::{Buf, Bytes};
use nex_core::bitfield::{self, u24be};
use crate::packet::{GenericMutablePacket, Packet};
pub struct VxlanPacket {
pub flags: u8,
pub reserved1: u24be,
pub vni: u24be,
pub reserved2: u8,
pub payload: Bytes,
}
impl Packet for VxlanPacket {
type Header = ();
fn from_buf(mut bytes: &[u8]) -> Option<Self> {
if bytes.len() < 8 {
return None;
}
let flags = bytes.get_u8();
let reserved1 = {
let b1 = bytes.get_u8();
let b2 = bytes.get_u8();
let b3 = bytes.get_u8();
bitfield::utils::u24be_from_bytes([b1, b2, b3])
};
let vni = {
let b1 = bytes.get_u8();
let b2 = bytes.get_u8();
let b3 = bytes.get_u8();
bitfield::utils::u24be_from_bytes([b1, b2, b3])
};
let reserved2 = bytes.get_u8();
let payload = Bytes::copy_from_slice(bytes);
Some(Self {
flags,
reserved1,
vni,
reserved2,
payload,
})
}
fn from_bytes(bytes: Bytes) -> Option<Self> {
Self::from_buf(&bytes)
}
fn to_bytes(&self) -> Bytes {
use bytes::BufMut;
let mut buf = bytes::BytesMut::with_capacity(8 + self.payload.len());
buf.put_u8(self.flags);
buf.put_slice(&bitfield::utils::u24be_to_bytes(self.reserved1));
buf.put_slice(&bitfield::utils::u24be_to_bytes(self.vni));
buf.put_u8(self.reserved2);
buf.put_slice(&self.payload);
buf.freeze()
}
fn header(&self) -> Bytes {
use bytes::BufMut;
let mut buf = bytes::BytesMut::with_capacity(8);
buf.put_u8(self.flags);
buf.put_slice(&self.reserved1.to_be_bytes());
buf.put_slice(&self.vni.to_be_bytes());
buf.put_u8(self.reserved2);
buf.freeze()
}
fn payload(&self) -> Bytes {
self.payload.clone()
}
fn header_len(&self) -> usize {
8
}
fn payload_len(&self) -> usize {
self.payload.len()
}
fn total_len(&self) -> usize {
self.header_len() + self.payload_len()
}
fn into_parts(self) -> (Self::Header, Bytes) {
((), self.payload)
}
}
pub type MutableVxlanPacket<'a> = GenericMutablePacket<'a, VxlanPacket>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn vxlan_packet_test() {
let packet = Bytes::from_static(&[
0x08, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x00, ]);
let vxlan_packet = VxlanPacket::from_bytes(packet.clone()).unwrap();
assert_eq!(vxlan_packet.to_bytes(), packet);
}
#[test]
fn mutable_vxlan_packet_test() {
let mut raw = [0x08, 0x00, 0x00, 0x00, 0x12, 0x34, 0x56, 0x00, 0xaa];
use crate::packet::MutablePacket;
let mut packet =
<MutableVxlanPacket as MutablePacket>::new(&mut raw).expect("mutable vxlan");
packet.header_mut()[0] = 0x0c;
packet.payload_mut()[0] = 0xff;
let frozen = MutablePacket::freeze(&packet).expect("freeze");
assert_eq!(frozen.payload[0], 0xff);
}
}