1 use super::{VirtioNetHdr, NET_HDR_SIZE}; 2 use alloc::{vec, vec::Vec}; 3 use core::{convert::TryInto, mem::size_of}; 4 use zerocopy::IntoBytes; 5 6 /// A buffer used for transmitting. 7 pub struct TxBuffer(pub(crate) Vec<u8>); 8 9 /// A buffer used for receiving. 10 pub struct RxBuffer { 11 pub(crate) buf: Vec<usize>, // for alignment 12 pub(crate) packet_len: usize, 13 pub(crate) idx: u16, 14 } 15 16 impl TxBuffer { 17 /// Constructs the buffer from the given slice. from(buf: &[u8]) -> Self18 pub fn from(buf: &[u8]) -> Self { 19 Self(Vec::from(buf)) 20 } 21 22 /// Returns the network packet length. packet_len(&self) -> usize23 pub fn packet_len(&self) -> usize { 24 self.0.len() 25 } 26 27 /// Returns the network packet as a slice. packet(&self) -> &[u8]28 pub fn packet(&self) -> &[u8] { 29 self.0.as_slice() 30 } 31 32 /// Returns the network packet as a mutable slice. packet_mut(&mut self) -> &mut [u8]33 pub fn packet_mut(&mut self) -> &mut [u8] { 34 self.0.as_mut_slice() 35 } 36 } 37 38 impl RxBuffer { 39 /// Allocates a new buffer with length `buf_len`. new(idx: usize, buf_len: usize) -> Self40 pub(crate) fn new(idx: usize, buf_len: usize) -> Self { 41 Self { 42 buf: vec![0; buf_len / size_of::<usize>()], 43 packet_len: 0, 44 idx: idx.try_into().unwrap(), 45 } 46 } 47 48 /// Set the network packet length. set_packet_len(&mut self, packet_len: usize)49 pub(crate) fn set_packet_len(&mut self, packet_len: usize) { 50 self.packet_len = packet_len 51 } 52 53 /// Returns the network packet length (witout header). packet_len(&self) -> usize54 pub const fn packet_len(&self) -> usize { 55 self.packet_len 56 } 57 58 /// Returns all data in the buffer, including both the header and the packet. as_bytes(&self) -> &[u8]59 pub fn as_bytes(&self) -> &[u8] { 60 self.buf.as_bytes() 61 } 62 63 /// Returns all data in the buffer with the mutable reference, 64 /// including both the header and the packet. as_bytes_mut(&mut self) -> &mut [u8]65 pub fn as_bytes_mut(&mut self) -> &mut [u8] { 66 self.buf.as_mut_bytes() 67 } 68 69 /// Returns the reference of the header. header(&self) -> &VirtioNetHdr70 pub fn header(&self) -> &VirtioNetHdr { 71 unsafe { &*(self.buf.as_ptr() as *const VirtioNetHdr) } 72 } 73 74 /// Returns the network packet as a slice. packet(&self) -> &[u8]75 pub fn packet(&self) -> &[u8] { 76 &self.buf.as_bytes()[NET_HDR_SIZE..NET_HDR_SIZE + self.packet_len] 77 } 78 79 /// Returns the network packet as a mutable slice. packet_mut(&mut self) -> &mut [u8]80 pub fn packet_mut(&mut self) -> &mut [u8] { 81 &mut self.buf.as_mut_bytes()[NET_HDR_SIZE..NET_HDR_SIZE + self.packet_len] 82 } 83 } 84