Skip to content

edigaryev/vmnet

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vmnet

Docs.rs

Apple's vmnet.framework bindings for Rust.

Installation

Add this to your Cargo.toml:

[dependencies]
vmnet = "0"

Usage

Ensure that your software either has an com.apple.vm.networking entitlement or is running with elevated privileges.

Start a NAT interface and receive some packets destined to it:

let shared_mode = Shared {
    subnet_options: None,
    ..Default::default()
};

let mut iface = Interface::new(Mode::Shared(shared_mode), Options::default()).unwrap();

let (tx, rx) = sync::mpsc::sync_channel(0);

iface.set_event_callback(Events::PACKETS_AVAILABLE, move |events, params| {
    if let Some(Parameter::EstimatedPacketsAvailable(pkts)) = params.get(ParameterKind::EstimatedPacketsAvailable) {
        tx.send(pkts);
    }
}).unwrap();

let pkts = rx.recv().unwrap();
println!("receiving {} packets...", pkts);
for _ in 0..pkts {
    let mut buf: [u8; 1514] = [0; 1514];
    println!("{:?}", iface.read(&mut buf));
}

drop(rx);
iface.finalize().unwrap();

Quirks and missing functionality

  • due to Apple's usage of blocks as a way to retrieve API call results, some methods like set_event_callback() require the provided closure to have a 'static lifetime
    • this manifests itself in not being able to use Interface from such closure
    • however, this can be easily worked around by using interior mutability pattern or simply by using the callback as a signal carrier
  • no port forwarding support
  • due to API_AVAILABLE macro not being supported it is assumed that this package is running on macOS 11.0 or newer