use crate::error;
use crate::ffi::xpc::XpcObjectT;
use bitflags::bitflags;
use dispatch2::DispatchQueue;
use libc::{in6_addr, in_addr, iovec, size_t};
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::ffi::c_void;
use std::os::raw::{c_char, c_int};
pub type NetworkConfigurationRef = *mut c_void;
pub type NetworkRef = *mut c_void;
pub type InterfaceRef = *mut c_void;
pub type InterfaceEventT = u32;
pub type VmnetReturnT = u32;
#[repr(C)]
#[derive(Debug)]
pub struct vmpktdesc {
pub vm_pkt_size: size_t,
pub vm_pkt_iov: *mut iovec,
pub vm_pkt_iovcnt: u32,
pub vm_flags: u32,
}
unsafe impl Sync for vmpktdesc {}
#[link(name = "vmnet", kind = "framework")]
extern "C" {
pub fn vmnet_network_configuration_create(
mode: u32,
status: *mut VmnetReturnT,
) -> NetworkConfigurationRef;
pub fn vmnet_network_configuration_set_external_interface(
config: NetworkConfigurationRef,
interface_name: *const c_char,
) -> VmnetReturnT;
pub fn vmnet_network_configuration_disable_nat44(config: NetworkConfigurationRef);
pub fn vmnet_network_configuration_disable_nat66(config: NetworkConfigurationRef);
pub fn vmnet_network_configuration_disable_dhcp(config: NetworkConfigurationRef);
pub fn vmnet_network_configuration_disable_dns_proxy(config: NetworkConfigurationRef);
pub fn vmnet_network_configuration_disable_router_advertisement(
config: NetworkConfigurationRef,
);
pub fn vmnet_network_configuration_set_ipv4_subnet(
config: NetworkConfigurationRef,
subnet_addr: *const in_addr,
subnet_mask: *const in_addr,
) -> VmnetReturnT;
pub fn vmnet_network_configuration_set_ipv6_prefix(
config: NetworkConfigurationRef,
prefix: *const in6_addr,
len: u8,
) -> VmnetReturnT;
pub fn vmnet_network_configuration_set_mtu(
config: NetworkConfigurationRef,
mtu: u32,
) -> VmnetReturnT;
pub fn vmnet_network_configuration_add_dhcp_reservation(
config: NetworkConfigurationRef,
client: *const [u8; 6],
reservation: *const in_addr,
) -> VmnetReturnT;
pub fn vmnet_network_configuration_add_port_forwarding_rule(
config: NetworkConfigurationRef,
protocol: u8,
address_family: u8,
internal_port: u16,
external_port: u16,
internal_address: *const c_void,
) -> VmnetReturnT;
pub fn vmnet_network_create(
configuration: NetworkConfigurationRef,
status: *mut VmnetReturnT,
) -> NetworkRef;
pub fn vmnet_network_get_ipv4_subnet(
network: NetworkRef,
subnet: *mut in_addr,
mask: *mut in_addr,
);
pub fn vmnet_network_get_ipv6_prefix(
network: NetworkRef,
prefix: *mut in6_addr,
prefix_len: *mut u8,
);
pub fn vmnet_start_interface(
interface_desc: XpcObjectT,
queue: &DispatchQueue,
handler: *mut c_void,
) -> InterfaceRef;
pub fn vmnet_interface_start_with_network(
network: NetworkRef,
interface_desc: XpcObjectT,
queue: &DispatchQueue,
start_block: *mut c_void,
) -> InterfaceRef;
pub fn vmnet_interface_set_event_callback(
interface: InterfaceRef,
event_mask: InterfaceEventT,
queue: Option<&DispatchQueue>,
callback: *mut c_void,
) -> VmnetReturnT;
pub fn vmnet_read(
interface: InterfaceRef,
packets: *mut vmpktdesc,
pktcnt: *mut c_int,
) -> VmnetReturnT;
pub fn vmnet_write(
interface: InterfaceRef,
packets: *mut vmpktdesc,
pktcnt: *mut c_int,
) -> VmnetReturnT;
pub fn vmnet_stop_interface(
interface: InterfaceRef,
queue: &DispatchQueue,
handler: *mut c_void,
) -> VmnetReturnT;
pub fn vmnet_interface_add_ip_port_forwarding_rule(
interface: InterfaceRef,
protocol: u8,
external_port: u16,
address_family: u8,
internal_address: *const c_void,
internal_port: u16,
handler: *mut c_void,
) -> VmnetReturnT;
pub fn vmnet_interface_get_ip_port_forwarding_rules(
interface: InterfaceRef,
address_family: u8,
handler: *mut c_void,
) -> VmnetReturnT;
pub fn vmnet_ip_port_forwarding_rule_get_details(
rule: XpcObjectT,
protocol: *mut u8,
external_port: *mut u16,
address_family: u8,
internal_address: *mut c_void,
internal_port: *mut u16,
) -> VmnetReturnT;
pub fn vmnet_interface_remove_ip_port_forwarding_rule(
interface: InterfaceRef,
protocol: u8,
external_port: u16,
address_family: u8,
handler: *mut c_void,
) -> VmnetReturnT;
pub fn vmnet_copy_shared_interface_list() -> XpcObjectT;
pub static vmnet_operation_mode_key: *const c_char;
pub static vmnet_mac_address_key: *const c_char;
pub static vmnet_allocate_mac_address_key: *const c_char;
pub static vmnet_interface_id_key: *const c_char;
pub static vmnet_max_packet_size_key: *const c_char;
pub static vmnet_read_max_packets_key: *const c_char;
pub static vmnet_write_max_packets_key: *const c_char;
pub static vmnet_enable_checksum_offload_key: *const c_char;
pub static vmnet_enable_isolation_key: *const c_char;
pub static vmnet_enable_tso_key: *const c_char;
pub static vmnet_network_identifier_key: *const c_char;
pub static vmnet_host_ip_address_key: *const c_char;
pub static vmnet_host_ipv6_address_key: *const c_char;
pub static vmnet_host_subnet_mask_key: *const c_char;
pub static vmnet_shared_interface_name_key: *const c_char;
pub static vmnet_start_address_key: *const c_char;
pub static vmnet_end_address_key: *const c_char;
pub static vmnet_subnet_mask_key: *const c_char;
pub static vmnet_mtu_key: *const c_char;
pub static vmnet_nat66_prefix_key: *const c_char;
pub static vmnet_estimated_packets_available_key: *const c_char;
}
#[derive(TryFromPrimitive)]
#[repr(u32)]
#[derive(Debug, Eq, PartialEq)]
pub enum Status {
Success = 1000,
Failure = 1001,
MemFailure = 1002,
InvalidArgument = 1003,
SetupIncomplete = 1004,
InvalidAccess = 1005,
PacketTooBig = 1006,
BufferExhausted = 1007,
TooManyPackets = 1008,
SharingServiceBusy = 1009,
NotAuthorized = 1010,
}
impl Status {
pub fn from_ffi(status: u32) -> Result<(), error::Error> {
let status =
Status::try_from(status).map_err(|_x| error::Error::VmnetUnknownStatus(status))?;
match status {
Status::Success => Ok(()),
_ => Err(error::Error::VmnetErrorStatus(status)),
}
}
}
#[repr(u64)]
#[derive(IntoPrimitive)]
pub enum Mode {
Host = 1000,
Shared = 1001,
Bridged = 1002,
}
bitflags! {
pub struct Events: u32 {
const PACKETS_AVAILABLE = 1 << 0;
}
}