vmnet/ffi/
vmnet.rs

1use crate::error;
2use crate::ffi::dispatch::DispatchQueueGlobalT;
3use crate::ffi::xpc::XpcObjectT;
4use bitflags::bitflags;
5use libc::{iovec, size_t};
6use num_enum::{IntoPrimitive, TryFromPrimitive};
7use std::ffi::c_void;
8use std::os::raw::{c_char, c_int};
9
10pub type InterfaceRef = *mut c_void;
11pub type InterfaceEventT = u32;
12pub type VmnetReturnT = u32;
13
14#[repr(C)]
15#[derive(Debug)]
16pub struct vmpktdesc {
17    pub vm_pkt_size: size_t,
18    pub vm_pkt_iov: *mut iovec,
19    pub vm_pkt_iovcnt: u32,
20    pub vm_flags: u32,
21}
22
23#[link(name = "vmnet", kind = "framework")]
24extern "C" {
25    // Interface functions
26    pub fn vmnet_start_interface(
27        interface_desc: XpcObjectT,
28        queue: DispatchQueueGlobalT,
29        handler: *mut c_void,
30    ) -> InterfaceRef;
31    pub fn vmnet_interface_set_event_callback(
32        interface: InterfaceRef,
33        event_mask: InterfaceEventT,
34        queue: DispatchQueueGlobalT,
35        handler: *mut c_void,
36    ) -> VmnetReturnT;
37    pub fn vmnet_read(
38        interface: InterfaceRef,
39        packets: *mut vmpktdesc,
40        pktcnt: *mut c_int,
41    ) -> VmnetReturnT;
42    pub fn vmnet_write(
43        interface: InterfaceRef,
44        packets: *mut vmpktdesc,
45        pktcnt: *mut c_int,
46    ) -> VmnetReturnT;
47    pub fn vmnet_stop_interface(
48        interface: InterfaceRef,
49        queue: DispatchQueueGlobalT,
50        handler: *mut c_void,
51    ) -> VmnetReturnT;
52
53    // Interface port forwarding functions
54    pub fn vmnet_interface_add_ip_port_forwarding_rule(
55        interface: InterfaceRef,
56        protocol: u8,
57        external_port: u16,
58        address_family: u8,
59        internal_address: *const c_void,
60        internal_port: u16,
61        handler: *mut c_void,
62    ) -> VmnetReturnT;
63    pub fn vmnet_interface_get_ip_port_forwarding_rules(
64        interface: InterfaceRef,
65        address_family: u8,
66        handler: *mut c_void,
67    ) -> VmnetReturnT;
68    pub fn vmnet_ip_port_forwarding_rule_get_details(
69        rule: XpcObjectT,
70        protocol: *mut u8,
71        external_port: *mut u16,
72        address_family: u8,
73        internal_address: *mut c_void,
74        internal_port: *mut u16,
75    ) -> VmnetReturnT;
76    pub fn vmnet_interface_remove_ip_port_forwarding_rule(
77        interface: InterfaceRef,
78        protocol: u8,
79        external_port: u16,
80        address_family: u8,
81        handler: *mut c_void,
82    ) -> VmnetReturnT;
83
84    // Utility functions
85    pub fn vmnet_copy_shared_interface_list() -> XpcObjectT;
86
87    // Mode selector
88    pub static vmnet_operation_mode_key: *const c_char;
89
90    // Generic options and parameters
91    pub static vmnet_mac_address_key: *const c_char;
92    pub static vmnet_allocate_mac_address_key: *const c_char;
93    pub static vmnet_interface_id_key: *const c_char;
94    pub static vmnet_max_packet_size_key: *const c_char;
95    pub static vmnet_read_max_packets_key: *const c_char;
96    pub static vmnet_write_max_packets_key: *const c_char;
97    pub static vmnet_enable_checksum_offload_key: *const c_char;
98    pub static vmnet_enable_isolation_key: *const c_char;
99    pub static vmnet_enable_tso_key: *const c_char;
100
101    // Host mode
102    pub static vmnet_network_identifier_key: *const c_char;
103    pub static vmnet_host_ip_address_key: *const c_char;
104    pub static vmnet_host_ipv6_address_key: *const c_char;
105    pub static vmnet_host_subnet_mask_key: *const c_char;
106
107    // Bridged mode
108    pub static vmnet_shared_interface_name_key: *const c_char;
109
110    // Shared and host modes
111    pub static vmnet_start_address_key: *const c_char;
112    pub static vmnet_end_address_key: *const c_char;
113    pub static vmnet_subnet_mask_key: *const c_char;
114    pub static vmnet_mtu_key: *const c_char;
115
116    // Shared mode
117    pub static vmnet_nat66_prefix_key: *const c_char;
118
119    // Event callback
120    pub static vmnet_estimated_packets_available_key: *const c_char;
121}
122
123/// A status returned by the [vmnet.framework](https://developer.apple.com/documentation/vmnet).
124#[derive(TryFromPrimitive)]
125#[repr(u32)]
126#[derive(Debug, Eq, PartialEq)]
127pub enum Status {
128    Success = 1000,
129    Failure = 1001,
130    MemFailure = 1002,
131    InvalidArgument = 1003,
132    SetupIncomplete = 1004,
133    InvalidAccess = 1005,
134    PacketTooBig = 1006,
135    BufferExhausted = 1007,
136    TooManyPackets = 1008,
137    SharingServiceBusy = 1009,
138}
139
140impl Status {
141    pub fn from_ffi(status: u32) -> Result<(), error::Error> {
142        let status =
143            Status::try_from(status).map_err(|_x| error::Error::VmnetUnknownStatus(status))?;
144
145        match status {
146            Status::Success => Ok(()),
147            _ => Err(error::Error::VmnetErrorStatus(status)),
148        }
149    }
150}
151
152#[repr(u64)]
153#[derive(IntoPrimitive)]
154pub enum Mode {
155    Host = 1000,
156    Shared = 1001,
157    Bridged = 1002,
158}
159
160bitflags! {
161    /// Describes events received for a given [interface callback call](crate::Interface::set_event_callback).
162    pub struct Events: u32 {
163        const PACKETS_AVAILABLE = 1 << 0;
164    }
165}