#![allow(dead_code)]
pub const VSOCK_PKT_HDR_SIZE: usize = 44;
pub const VSOCK_OP_REQUEST: u16 = 1;
pub const VSOCK_OP_RESPONSE: u16 = 2;
pub const VSOCK_OP_RST: u16 = 3;
pub const VSOCK_OP_SHUTDOWN: u16 = 4;
pub const VSOCK_OP_RW: u16 = 5;
pub const VSOCK_OP_CREDIT_UPDATE: u16 = 6;
pub const VSOCK_OP_CREDIT_REQUEST: u16 = 7;
pub const VSOCK_TYPE_STREAM: u16 = 1;
pub const VSOCK_TYPE_DGRAM: u16 = 3;
pub const VSOCK_HOST_CID: u64 = 2;
fn le_u16(b: &[u8; VSOCK_PKT_HDR_SIZE], off: usize) -> u16 {
u16::from_le_bytes([b[off], b[off + 1]])
}
fn le_u32(b: &[u8; VSOCK_PKT_HDR_SIZE], off: usize) -> u32 {
u32::from_le_bytes([b[off], b[off + 1], b[off + 2], b[off + 3]])
}
fn le_u64(b: &[u8; VSOCK_PKT_HDR_SIZE], off: usize) -> u64 {
u64::from_le_bytes([
b[off],
b[off + 1],
b[off + 2],
b[off + 3],
b[off + 4],
b[off + 5],
b[off + 6],
b[off + 7],
])
}
#[derive(Debug, Clone, Copy)]
pub struct Header {
pub src_cid: u64,
pub dst_cid: u64,
pub src_port: u32,
pub dst_port: u32,
pub len: u32,
pub type_: u16,
pub op: u16,
pub flags: u32,
pub buf_alloc: u32,
pub fwd_cnt: u32,
}
impl Header {
pub fn parse(b: &[u8; VSOCK_PKT_HDR_SIZE]) -> Self {
Self {
src_cid: le_u64(b, 0),
dst_cid: le_u64(b, 8),
src_port: le_u32(b, 16),
dst_port: le_u32(b, 20),
len: le_u32(b, 24),
type_: le_u16(b, 28),
op: le_u16(b, 30),
flags: le_u32(b, 32),
buf_alloc: le_u32(b, 36),
fwd_cnt: le_u32(b, 40),
}
}
pub fn encode(&self) -> [u8; VSOCK_PKT_HDR_SIZE] {
let mut b = [0u8; VSOCK_PKT_HDR_SIZE];
b[0..8].copy_from_slice(&self.src_cid.to_le_bytes());
b[8..16].copy_from_slice(&self.dst_cid.to_le_bytes());
b[16..20].copy_from_slice(&self.src_port.to_le_bytes());
b[20..24].copy_from_slice(&self.dst_port.to_le_bytes());
b[24..28].copy_from_slice(&self.len.to_le_bytes());
b[28..30].copy_from_slice(&self.type_.to_le_bytes());
b[30..32].copy_from_slice(&self.op.to_le_bytes());
b[32..36].copy_from_slice(&self.flags.to_le_bytes());
b[36..40].copy_from_slice(&self.buf_alloc.to_le_bytes());
b[40..44].copy_from_slice(&self.fwd_cnt.to_le_bytes());
b
}
}
#[derive(Debug, Clone)]
pub struct RxPacket {
pub hdr: Header,
pub data: Vec<u8>,
}
impl RxPacket {
pub fn control(
src_cid: u64,
dst_cid: u64,
src_port: u32,
dst_port: u32,
op: u16,
type_: u16,
) -> Self {
Self {
hdr: Header {
src_cid,
dst_cid,
src_port,
dst_port,
len: 0,
type_,
op,
flags: 0,
buf_alloc: 256 * 1024,
fwd_cnt: 0,
},
data: Vec::new(),
}
}
pub fn rst_for(req: &Header) -> Self {
Self::control(
req.dst_cid,
req.src_cid,
req.dst_port,
req.src_port,
VSOCK_OP_RST,
req.type_,
)
}
pub fn response_to(req: &Header) -> Self {
Self::control(
req.dst_cid,
req.src_cid,
req.dst_port,
req.src_port,
VSOCK_OP_RESPONSE,
req.type_,
)
}
}