adb_utils/commands/networking/
forward.rs

1use std::{fmt::Display, process::Command};
2
3use crate::{ADBCommand, ADBResult};
4
5/// List all forward socket connections
6pub struct ADBForward {
7    shell: Command,
8}
9
10pub enum ForwardMethodLocal {
11    /// May be 0 to pick any open port
12    Tcp(u32),
13    LocalAbstract(UDS),
14    LocalReserved(UDS),
15    LocalFilesystem(UDS),
16}
17
18pub enum ForwardMethodRemote {
19    Tcp(u32),
20    // LocalAbstract(UDS),
21    // LocalReserved(UDS),
22    // LocalFilesystem(UDS),
23    /// PID
24    Jdwp(u32),
25    /// CID, PID
26    Vsock(u32, u32),
27}
28
29impl ADBForward {
30    /// List all forward socket connections
31    pub fn list() -> Self {
32        let mut cmd = Command::new("adb");
33        cmd.arg("forward").arg("--list");
34
35        ADBForward { shell: cmd }
36    }
37
38    /// Forward socket connection using a local and remote method
39    pub fn using(local: ForwardMethodLocal, remote: ForwardMethodRemote) -> Self {
40        let mut cmd = Command::new("adb");
41        cmd.arg(match local {
42            ForwardMethodLocal::Tcp(port) => format!("tcp:{port}"),
43            ForwardMethodLocal::LocalAbstract(uds) => format!("localabstract:{uds}"),
44            ForwardMethodLocal::LocalReserved(uds) => format!("localreserved:{uds}"),
45            ForwardMethodLocal::LocalFilesystem(uds) => format!("localfilesystem:{uds}"),
46        });
47        cmd.arg(match remote {
48            ForwardMethodRemote::Tcp(port) => format!("tcp:{port}"),
49            // ForwardMethodRemote::LocalAbstract(_) => todo!(),
50            // ForwardMethodRemote::LocalReserved(_) => todo!(),
51            // ForwardMethodRemote::LocalFilesystem(_) => todo!(),
52            ForwardMethodRemote::Jdwp(pid) => format!("jdwp:{pid}"),
53            ForwardMethodRemote::Vsock(cid, pid) => format!("vsock:{cid}:{pid}"),
54        });
55
56        ADBForward { shell: cmd }
57    }
58}
59
60impl ADBCommand for ADBForward {
61    fn build(&mut self) -> Result<&mut Command, String> {
62        Ok(&mut self.shell)
63    }
64
65    fn process_output(&self, output: ADBResult) -> ADBResult {
66        output
67    }
68}
69
70/// Unix domain socket or IPC (https://en.wikipedia.org/wiki/Unix_domain_socket)
71pub enum UDS {
72    /// stream oriented
73    SockStream,
74    // datagram oriented, preserves message boundaries
75    SockDgram,
76    // connection oriented, sequenced-packet
77    SockSeqpacket,
78}
79
80impl Display for UDS {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        write!(
83            f,
84            "{}",
85            match self {
86                UDS::SockStream => "SOCK_STREAM",
87                UDS::SockDgram => "SOCK_DGRAM",
88                UDS::SockSeqpacket => "SOCK_SEQPACKET",
89            }
90        )
91    }
92}