diff --git a/lib/host.rs b/lib/host.rs index 32bd60c..2d60ba0 100644 --- a/lib/host.rs +++ b/lib/host.rs @@ -1,3 +1,4 @@ +use clap::ArgEnum; use anyhow::{anyhow, Context, Result}; use std::net::Ipv4Addr; use std::os::unix::io::{AsRawFd, RawFd}; @@ -8,6 +9,18 @@ use vmnet::mode::Mode; use vmnet::parameters::{Parameter, ParameterKind}; use vmnet::{Events, Options}; +#[derive(ArgEnum, Clone, Debug)] +pub enum NetType { + /// Shared network + /// + /// Uses NAT-translation to give guests access to the global network + Nat, + /// Host network + /// + /// Guests will be able to talk only to the host without access to global network + Host, +} + pub struct Host { interface: vmnet::Interface, new_packets_rx: UnixDatagram, @@ -18,10 +31,13 @@ pub struct Host { } impl Host { - pub fn new() -> Result { - // Initialize a vmnet.framework NAT interface with isolation enabled + pub fn new(vm_net_type: NetType) -> Result { + // Initialize a vmnet.framework NAT or Host interface with isolation enabled let mut interface = vmnet::Interface::new( - Mode::Shared(Default::default()), + match vm_net_type { + NetType::Nat => Mode::Shared(Default::default()), + NetType::Host => Mode::Host(Default::default()), + }, Options { enable_isolation: Some(true), ..Default::default() diff --git a/lib/mod.rs b/lib/mod.rs index 76bcec0..838640f 100644 --- a/lib/mod.rs +++ b/lib/mod.rs @@ -1,5 +1,6 @@ mod dhcp_snooper; mod host; +pub use host::NetType; mod poller; pub mod proxy; mod vm; diff --git a/lib/proxy/mod.rs b/lib/proxy/mod.rs index 4b50881..6a79ceb 100644 --- a/lib/proxy/mod.rs +++ b/lib/proxy/mod.rs @@ -4,6 +4,7 @@ mod vm; use crate::dhcp_snooper::DhcpSnooper; use crate::host::Host; +use crate::host::NetType; use crate::poller::Poller; use crate::vm::VM; use anyhow::Result; @@ -22,9 +23,9 @@ pub struct Proxy { } impl Proxy { - pub fn new(vm_fd: RawFd, vm_mac_address: MacAddress) -> Result { + pub fn new(vm_fd: RawFd, vm_mac_address: MacAddress, vm_net_type: NetType) -> Result { let vm = VM::new(vm_fd)?; - let host = Host::new()?; + let host = Host::new(vm_net_type)?; let poller = Poller::new(vm.as_raw_fd(), host.as_raw_fd())?; Ok(Proxy { diff --git a/src/main.rs b/src/main.rs index bb18be6..cca1369 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use anyhow::{anyhow, Context}; use clap::Parser; use nix::sys::signal::{signal, SigHandler, Signal}; use privdrop::PrivDrop; +use softnet::NetType; use softnet::proxy::Proxy; use std::borrow::Cow; use std::env; @@ -28,6 +29,9 @@ struct Args { #[clap(long, help = "MAC address to enforce for the VM")] vm_mac_address: mac_address::MacAddress, + #[clap(long, arg_enum, help = "type of network to use for the VM", default_value_t=NetType::Nat)] + vm_net_type: NetType, + #[clap( long, help = "set bootpd(8) lease time to this value (in seconds) before starting the VM", @@ -140,7 +144,7 @@ fn try_main() -> anyhow::Result<()> { set_bootpd_lease_time(args.bootpd_lease_time); // Initialize the proxy while still having the root privileges - let mut proxy = Proxy::new(args.vm_fd as RawFd, args.vm_mac_address) + let mut proxy = Proxy::new(args.vm_fd as RawFd, args.vm_mac_address, args.vm_net_type) .context("failed to initialize proxy")?; // Drop effective privileges to the user