Skip to main content

vm_ch/
network.rs

1use std::cell::Cell;
2use std::os::unix::io::RawFd;
3
4pub struct FileHandleNetworkAttachment {
5    pub(crate) fd: RawFd,
6}
7
8impl FileHandleNetworkAttachment {
9    /// Creates a network attachment from a connected datagram socket fd.
10    /// The fd should be one end of `socketpair(AF_UNIX, SOCK_DGRAM)`.
11    pub fn new(fd: RawFd) -> Self {
12        FileHandleNetworkAttachment { fd }
13    }
14}
15
16pub struct MACAddress {
17    pub(crate) bytes: [u8; 6],
18}
19
20impl MACAddress {
21    pub fn new() -> Self {
22        MACAddress { bytes: [0; 6] }
23    }
24
25    /// Generate a random locally-administered MAC address.
26    pub fn random_local() -> Self {
27        let mut bytes = [0u8; 6];
28        let fd = unsafe { libc::open(c"/dev/urandom".as_ptr(), libc::O_RDONLY) };
29        if fd >= 0 {
30            unsafe {
31                libc::read(fd, bytes.as_mut_ptr() as *mut libc::c_void, 6);
32                libc::close(fd);
33            }
34        }
35        // Set locally administered + unicast bits
36        bytes[0] = (bytes[0] & 0xFC) | 0x02;
37        MACAddress { bytes }
38    }
39}
40
41impl Default for MACAddress {
42    fn default() -> Self {
43        Self::new()
44    }
45}
46
47pub struct VirtioNetworkDevice {
48    pub(crate) fd: Option<RawFd>,
49    pub(crate) mac: Cell<[u8; 6]>,
50}
51
52impl VirtioNetworkDevice {
53    pub fn new() -> Self {
54        VirtioNetworkDevice {
55            fd: None,
56            mac: Cell::new([0; 6]),
57        }
58    }
59
60    pub fn new_with_attachment(attachment: &FileHandleNetworkAttachment) -> Self {
61        VirtioNetworkDevice {
62            fd: Some(attachment.fd),
63            mac: Cell::new([0; 6]),
64        }
65    }
66
67    pub fn set_attachment(&mut self, attachment: &FileHandleNetworkAttachment) {
68        self.fd = Some(attachment.fd);
69    }
70
71    pub fn set_mac_address(&self, address: &MACAddress) {
72        self.mac.set(address.bytes);
73    }
74
75    pub(crate) fn mac_bytes(&self) -> [u8; 6] {
76        self.mac.get()
77    }
78}
79
80impl Default for VirtioNetworkDevice {
81    fn default() -> Self {
82        Self::new()
83    }
84}