summaryrefslogtreecommitdiffhomepage
path: root/mullvad-cli/src/cmds
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2020-02-26 13:07:02 +0100
committerDavid Lönnhager <david.l@mullvad.net>2020-06-02 10:05:01 +0200
commitd20979f07e671c50700304ffdabf7854788e85d6 (patch)
tree9fea81622fa5e8d142c9fb8773030a9566d3d543 /mullvad-cli/src/cmds
parent5bb52620f9b7bbbc0bd24bfe03e4cfcfb5a0b16a (diff)
downloadmullvadvpn-d20979f07e671c50700304ffdabf7854788e85d6.tar.xz
mullvadvpn-d20979f07e671c50700304ffdabf7854788e85d6.zip
Add split tunneling CLI
Diffstat (limited to 'mullvad-cli/src/cmds')
-rw-r--r--mullvad-cli/src/cmds/mod.rs7
-rw-r--r--mullvad-cli/src/cmds/split.rs65
2 files changed, 72 insertions, 0 deletions
diff --git a/mullvad-cli/src/cmds/mod.rs b/mullvad-cli/src/cmds/mod.rs
index 699b62ba1d..5631ae03b4 100644
--- a/mullvad-cli/src/cmds/mod.rs
+++ b/mullvad-cli/src/cmds/mod.rs
@@ -34,6 +34,11 @@ pub use self::relay::Relay;
mod reset;
pub use self::reset::Reset;
+#[cfg(unix)]
+mod split;
+#[cfg(unix)]
+pub use self::split::Split;
+
mod status;
pub use self::status::Status;
@@ -57,6 +62,8 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
Box::new(Lan),
Box::new(Relay),
Box::new(Reset),
+ #[cfg(unix)]
+ Box::new(Split),
Box::new(Status),
Box::new(Tunnel),
Box::new(Version),
diff --git a/mullvad-cli/src/cmds/split.rs b/mullvad-cli/src/cmds/split.rs
new file mode 100644
index 0000000000..3aee1b0b1c
--- /dev/null
+++ b/mullvad-cli/src/cmds/split.rs
@@ -0,0 +1,65 @@
+use crate::{new_rpc_client, Command, Result};
+use clap::value_t_or_exit;
+
+pub struct Split;
+
+impl Command for Split {
+ fn name(&self) -> &'static str {
+ "split-tunnel"
+ }
+
+ fn clap_subcommand(&self) -> clap::App<'static, 'static> {
+ clap::SubCommand::with_name(self.name())
+ .about("Manage split tunneling")
+ .setting(clap::AppSettings::SubcommandRequiredElseHelp)
+ .subcommand(create_pid_subcommand())
+ }
+
+ fn run(&self, matches: &clap::ArgMatches<'_>) -> Result<()> {
+ match matches.subcommand() {
+ ("pid", Some(pid_matches)) => Self::handle_pid_cmd(pid_matches),
+ _ => unreachable!("unhandled comand"),
+ }
+ }
+}
+
+fn create_pid_subcommand() -> clap::App<'static, 'static> {
+ clap::SubCommand::with_name("pid")
+ .about("Manage processes to exclude from the tunnel")
+ .setting(clap::AppSettings::SubcommandRequiredElseHelp)
+ .subcommand(
+ clap::SubCommand::with_name("add").arg(clap::Arg::with_name("pid").required(true)),
+ )
+ .subcommand(
+ clap::SubCommand::with_name("delete").arg(clap::Arg::with_name("pid").required(true)),
+ )
+ .subcommand(clap::SubCommand::with_name("list"))
+}
+
+impl Split {
+ fn handle_pid_cmd(matches: &clap::ArgMatches<'_>) -> Result<()> {
+ match matches.subcommand() {
+ ("add", Some(matches)) => {
+ let pid = value_t_or_exit!(matches.value_of("pid"), i32);
+ new_rpc_client()?.add_split_tunnel_process(pid)?;
+ Ok(())
+ }
+ ("delete", Some(matches)) => {
+ let pid = value_t_or_exit!(matches.value_of("pid"), i32);
+ new_rpc_client()?.remove_split_tunnel_process(pid)?;
+ Ok(())
+ }
+ ("list", Some(_)) => {
+ let pids = new_rpc_client()?.get_split_tunnel_processes()?;
+ println!("Excluded PIDs:");
+
+ for pid in pids.iter() {
+ println!(" {}", pid);
+ }
+
+ Ok(())
+ }
+ _ => unreachable!("unhandled command"),
+ }
+ }
+}