vmm/dumbo/
mod.rs

1// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4//! Provides helper logic for parsing and writing protocol data units, and minimalist
5//! implementations of a TCP listener, a TCP connection, and an HTTP/1.1 server.
6pub mod pdu;
7pub mod tcp;
8
9use std::ops::Index;
10
11pub use crate::dumbo::pdu::arp::{ETH_IPV4_FRAME_LEN, EthIPv4ArpFrame};
12pub use crate::dumbo::pdu::ethernet::{
13    ETHERTYPE_ARP, ETHERTYPE_IPV4, EthernetFrame, PAYLOAD_OFFSET as ETHERNET_PAYLOAD_OFFSET,
14};
15pub use crate::dumbo::pdu::ipv4::{IPv4Packet, PROTOCOL_TCP, PROTOCOL_UDP};
16pub use crate::dumbo::pdu::udp::{UDP_HEADER_SIZE, UdpDatagram};
17use crate::utils::net::mac::MacAddr;
18
19/// Represents a generalization of a borrowed `[u8]` slice.
20#[allow(clippy::len_without_is_empty)]
21pub trait ByteBuffer: Index<usize, Output = u8> {
22    /// Returns the length of the buffer.
23    fn len(&self) -> usize;
24
25    /// Reads `buf.len()` bytes from `self` into `buf`, starting at `offset`.
26    ///
27    /// # Panics
28    ///
29    /// Panics if `offset + buf.len()` > `self.len()`.
30    fn read_to_slice(&self, offset: usize, buf: &mut [u8]);
31}
32
33impl ByteBuffer for [u8] {
34    #[inline]
35    fn len(&self) -> usize {
36        self.len()
37    }
38
39    #[inline]
40    fn read_to_slice(&self, offset: usize, buf: &mut [u8]) {
41        let buf_len = buf.len();
42        buf.copy_from_slice(&self[offset..offset + buf_len]);
43    }
44}
45
46#[cfg(test)]
47mod tests {
48    use std::fmt::Debug;
49
50    use super::*;
51
52    fn bb_len<T: ByteBuffer + ?Sized + Debug>(buf: &T) -> usize {
53        buf.len()
54    }
55
56    fn bb_is_empty<T: ByteBuffer + ?Sized + Debug>(buf: &T) -> bool {
57        buf.len() == 0
58    }
59
60    fn bb_read_from_1<T: ByteBuffer + ?Sized + Debug>(src: &T, dst: &mut [u8]) {
61        src.read_to_slice(1, dst);
62    }
63
64    #[test]
65    fn test_u8_byte_buffer() {
66        let a = [1u8, 2, 3];
67        let mut b = [0u8; 2];
68        assert_eq!(bb_len(a.as_ref()), a.len());
69        assert!(!bb_is_empty(a.as_ref()));
70        bb_read_from_1(a.as_ref(), b.as_mut());
71        assert_eq!(b, [2, 3]);
72    }
73}