### Start Phantun server with hostname Source: https://github.com/dndx/phantun/blob/main/README.md Start the server listening on a local TCP port and connecting to a remote UDP server using a hostname. ```bash RUST_LOG=info /usr/local/bin/phantun_server --local 4567 --remote example.com:1234 ``` -------------------------------- ### Start Phantun client with hostname Source: https://github.com/dndx/phantun/blob/main/README.md Start the client listening on a local UDP address and connecting to a remote Phantun server using a hostname. ```bash RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote example.com:4567 ``` -------------------------------- ### Start Phantun server with IP address Source: https://github.com/dndx/phantun/blob/main/README.md Start the server listening on a local TCP port and connecting to a remote UDP server using an IP address. ```bash RUST_LOG=info /usr/local/bin/phantun_server --local 4567 --remote 127.0.0.1:1234 ``` -------------------------------- ### Start Phantun client with IP address Source: https://github.com/dndx/phantun/blob/main/README.md Start the client listening on a local UDP address and connecting to a remote Phantun server using an IP address. ```bash RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote 10.0.0.1:4567 ``` -------------------------------- ### Socket Logging Example Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-socket.md Shows how the Display implementation is used for logging connection details. ```rust info!("New connection: {}", socket); // Output: New connection: (Fake TCP connection from 192.168.200.1:8080 to 192.168.200.2:9090) ``` -------------------------------- ### Start Phantun client with IPv6 address Source: https://github.com/dndx/phantun/blob/main/README.md Start the client connecting to a remote Phantun server using an IPv6 address. ```bash RUST_LOG=info /usr/local/bin/phantun_client --local 127.0.0.1:1234 --remote [fdxx::1234]:4567 ``` -------------------------------- ### get_source usage example Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/packet-module.md Demonstrates how to extract and print the source IP address from an IPPacket. ```rust let source = ip_packet.get_source(); println!("Source: {}", source); ``` -------------------------------- ### Example usage of assign_ipv6_address Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/phantun-utils.md A practical example showing how to import and call the assign_ipv6_address function to configure a TUN interface. ```rust use phantun::utils::assign_ipv6_address; use std::net::Ipv6Addr; let local = Ipv6Addr::new(0xfcc9, 0, 0, 0, 0, 0, 0, 1); let peer = Ipv6Addr::new(0xfcc9, 0, 0, 0, 0, 0, 0, 2); assign_ipv6_address("tun0", local, peer); // tun0 now has IPv6 addresses configured ``` -------------------------------- ### Initialize Stack with TunBuilder Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Example of creating a Stack instance using a TUN interface built with tokio_tun. ```rust use tokio_tun::TunBuilder; use fake_tcp::Stack; use std::net::Ipv4Addr; #[tokio::main] async fn main() { let tun = TunBuilder::new() .name("tun0") .address(Ipv4Addr::new(192, 168, 1, 1)) .destination(Ipv4Addr::new(192, 168, 1, 2)) .up() .build() .unwrap(); let mut stack = Stack::new( vec![tun], Ipv4Addr::new(192, 168, 1, 1), None ); } ``` -------------------------------- ### udp_recv_pktinfo usage example Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/phantun-utils.md Demonstrates using a loop to receive datagrams and print source and destination addresses. ```rust use phantun::utils::new_udp_reuseport; use std::net::SocketAddr; #[tokio::main] async fn main() -> std::io::Result<()> { let sock = new_udp_reuseport("0.0.0.0:1234".parse().unwrap()); let mut buf = [0u8; 1500]; loop { match sock.async_io(Interest::READABLE, || { // (internally uses recvmsg) }).await { Ok((size, src_addr, dst_addr)) => { println!( "Received {} bytes from {} to {}", size, src_addr, dst_addr ); } Err(e) => eprintln!("Error: {}", e), } } } ``` -------------------------------- ### Implement a Server Using fake-tcp Source: https://github.com/dndx/phantun/blob/main/_autodocs/README.md Example of setting up a TUN interface and listening for incoming connections using the fake-tcp Stack. ```rust use fake_tcp::Stack; use tokio_tun::TunBuilder; #[tokio::main] async fn main() { let tun = TunBuilder::new() .name("tun0") .address(Ipv4Addr::new(192, 168, 1, 1)) .destination(Ipv4Addr::new(192, 168, 1, 2)) .build() .unwrap(); let mut stack = Stack::new(vec![tun], Ipv4Addr::new(192, 168, 1, 1), None); stack.listen(8080); loop { let socket = stack.accept().await; tokio::spawn(async move { let mut buf = [0u8; 1500]; while let Some(size) = socket.recv(&mut buf).await { socket.send(&buf[..size]).await; } }); } } ``` -------------------------------- ### Client nftables Firewall Rules Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Example nftables configuration for the client to handle NAT postrouting. ```nftables table inet nat { chain postrouting { type nat hook postrouting priority srcnat; policy accept; iifname tun0 oif eth0 masquerade } } ``` -------------------------------- ### new_udp_reuseport usage example Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/phantun-utils.md Demonstrates creating a socket and binding multiple threads to the same port using SO_REUSEPORT. ```rust use phantun::utils::new_udp_reuseport; use std::net::SocketAddr; // Create socket on all interfaces let addr: SocketAddr = "0.0.0.0:1234".parse().unwrap(); let sock = new_udp_reuseport(addr); // Multiple threads can bind to the same port let sock1 = new_udp_reuseport(addr); let sock2 = new_udp_reuseport(addr); // Both sockets can receive from the same port due to SO_REUSEPORT ``` -------------------------------- ### Run Phantun Server CLI Source: https://github.com/dndx/phantun/blob/main/_autodocs/binary-interfaces.md The command-line interface for starting the Phantun server, requiring local and remote port configurations. ```bash phantun_server [OPTIONS] --local --remote ``` -------------------------------- ### Server nftables Firewall Rules Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Example nftables configuration for the server to handle NAT prerouting. ```nftables table inet nat { chain prerouting { type nat hook prerouting priority dstnat; policy accept; iif eth0 tcp dport 4567 dnat ip to 192.168.201.2 iif eth0 tcp dport 4567 dnat ip6 to fcc9::2 } } ``` -------------------------------- ### Implement a Client Using fake-tcp Source: https://github.com/dndx/phantun/blob/main/_autodocs/README.md Example of connecting to a remote address using the fake-tcp Stack and performing basic send/receive operations. ```rust let mut stack = Stack::new(vec![tun], Ipv4Addr::new(192, 168, 1, 1), None); let remote = "203.0.113.1:8080".parse().unwrap(); if let Some(socket) = stack.connect(remote).await { socket.send(b"Hello").await; let mut buf = [0u8; 1500]; if let Some(size) = socket.recv(&mut buf).await { println!("Received: {:?}", &buf[..size]); } } ``` -------------------------------- ### Set RUST_LOG Environment Variable Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Example of setting the logging level for the phantun_server binary. ```bash RUST_LOG=info phantun_server --local 4567 --remote 127.0.0.1:1234 ``` -------------------------------- ### Constructing TCP packets with build_tcp_packet Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/packet-module.md Example showing how to construct both a SYN packet and an ACK packet with a payload using the build_tcp_packet function. ```rust use fake_tcp::packet::build_tcp_packet; use pnet::packet::tcp; use std::net::{SocketAddr, IpAddr, Ipv4Addr}; let local = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080); let remote = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 1)), 4567); // Construct SYN packet let syn_packet = build_tcp_packet( local, remote, 1000, // sequence number 0, // ack number (not relevant for SYN) tcp::TcpFlags::SYN, None, ); // Construct ACK packet with payload let payload = b"Hello"; let ack_packet = build_tcp_packet( local, remote, 1001, 5000, tcp::TcpFlags::ACK, Some(payload), ); ``` -------------------------------- ### Parsing packets with parse_ip_packet Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/packet-module.md Example demonstrating how to parse a raw packet buffer and extract header information and payload. ```rust use bytes::Bytes; use fake_tcp::packet::parse_ip_packet; let buf = Bytes::from_static(raw_packet_bytes); if let Some((ip_pkt, tcp_pkt)) = parse_ip_packet(&buf) { let src = ip_pkt.get_source(); let dst = ip_pkt.get_destination(); let seq = tcp_pkt.get_sequence(); let ack = tcp_pkt.get_acknowledgement(); let flags = tcp_pkt.get_flags(); let payload = tcp_pkt.payload(); println!("Packet from {} to {}, seq={}, ack={}", src, dst, seq, ack); } else { println!("Not a TCP packet or invalid format"); } ``` -------------------------------- ### Automatic Socket Cleanup Example Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-socket.md Demonstrates how a socket is automatically dropped and an RST packet is sent when it goes out of scope. ```rust { let socket = stack.accept().await; socket.send(b"Goodbye").await; } // Socket is dropped here, RST is sent automatically ``` -------------------------------- ### Error Recovery in Client Source: https://github.com/dndx/phantun/blob/main/_autodocs/errors.md Example of handling connection errors and retries within a main loop using tokio. ```rust #[tokio::main] async fn main() -> io::Result<()> { loop { // Accept incoming UDP match udp_recv_pktinfo(&udp_sock, &mut buf).await { Ok((size, src_addr, dst_addr)) => { // Check for existing connection if let Some(sock) = connections.read().await.get(&src_addr) { if sock.send(&buf[..size]).await.is_none() { connections.write().await.remove(&src_addr); info!("Removed broken connection"); continue; } } else { // Create new connection match stack.connect(remote_addr).await { Some(sock) => { connections.write().await.insert(src_addr, Arc::new(sock)); } None => { error!("Unable to connect to remote"); continue; } } } } Err(e) => { error!("UDP receive error: {}", e); continue; } } } } ``` -------------------------------- ### Phantun Log Format Source: https://github.com/dndx/phantun/blob/main/_autodocs/binary-interfaces.md The standard log output format used by the server, followed by an example of typical runtime logs. ```text [TIMESTAMP] [LEVEL] [MODULE] MESSAGE ``` ```text [2024-01-15T10:30:45Z] [INFO] [phantun] Created TUN device tun0 [2024-01-15T10:30:45Z] [INFO] [fake_tcp] Listening on 4567 [2024-01-15T10:30:50Z] [INFO] [fake_tcp] New connection: (Fake TCP connection from 203.0.113.1:54321 to 192.168.201.2:4567) ``` -------------------------------- ### Basic Server Configuration (IPv4 only) Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Run the server with basic IPv4 settings. ```bash RUST_LOG=info /usr/local/bin/phantun_server \ --local 4567 \ --remote 127.0.0.1:1234 \ --ipv4-only ``` -------------------------------- ### Client to Remote Server Configuration Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Run the client to connect to a remote server with specific TUN addresses. ```bash RUST_LOG=info /usr/local/bin/phantun_client \ --local 127.0.0.1:1234 \ --remote vpn.company.com:4567 \ --tun-local 192.168.100.1 \ --tun-peer 192.168.100.2 ``` -------------------------------- ### Phantun Client CLI Usage Source: https://github.com/dndx/phantun/blob/main/_autodocs/binary-interfaces.md The standard command-line syntax for initiating the Phantun client with local and remote address specifications. ```bash phantun_client [OPTIONS] --local --remote ``` -------------------------------- ### Server with Custom TUN Addresses Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Run the server specifying custom local and peer addresses for both IPv4 and IPv6. ```bash RUST_LOG=info /usr/local/bin/phantun_server \ --local 4567 \ --remote example.com:8080 \ --tun-local 10.0.0.1 \ --tun-peer 10.0.0.2 \ --tun-local6 fd00::1 \ --tun-peer6 fd00::2 ``` -------------------------------- ### Project Directory Structure Source: https://github.com/dndx/phantun/blob/main/_autodocs/README.md The workspace layout showing the core fake-tcp library and the Phantun tunnel binaries. ```text phantun/ # Root workspace ├── Cargo.toml # Workspace root ├── fake-tcp/ # Core TCP stack library │ ├── Cargo.toml │ ├── src/ │ │ ├── lib.rs # Stack, Socket, State enums │ │ └── packet.rs # Packet building and parsing │ └── README.md ├── phantun/ # Phantun tunnel binaries │ ├── Cargo.toml │ ├── src/ │ │ ├── lib.rs # Library exports (utils module, UDP_TTL) │ │ ├── utils.rs # UDP socket and TUN utilities │ │ └── bin/ │ │ ├── client.rs # Phantun Client binary │ │ └── server.rs # Phantun Server binary │ └── README.md ├── README.md # Project README └── LICENSE-* # MIT and Apache 2.0 licenses ``` -------------------------------- ### Stack::accept Source: https://github.com/dndx/phantun/blob/main/_autodocs/types.md Accepts an incoming connection. ```APIDOC ### Method `accept(&mut self) -> Socket` ### Description Blocks until an incoming connection is established and returns the resulting Socket. ``` -------------------------------- ### Configure --handshake-packet file path Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Specifies a file to send as the first packet after the TCP handshake. File size must not exceed MTU. ```text --handshake-packet ``` -------------------------------- ### IPv6 Address Configuration Error Log Source: https://github.com/dndx/phantun/blob/main/_autodocs/errors.md Example of the panic output generated when a NETLINK socket operation fails during IPv6 address assignment. ```text thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ...' ``` -------------------------------- ### Stack::new Source: https://github.com/dndx/phantun/blob/main/_autodocs/types.md Creates a new virtual TCP stack. ```APIDOC ### Method `new(tun, local_ip, local_ip6) -> Stack` ### Description Initializes a new virtual TCP stack with the provided TUN interface and IP addresses. ``` -------------------------------- ### Implement UDP_TTL idle timeout Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/phantun-lib.md Example usage of UDP_TTL within a tokio select loop to monitor packet activity and close idle connections. ```rust use phantun::UDP_TTL; use tokio::time; loop { tokio::select! { _ = time::sleep(UDP_TTL) => { println!("Connection idle for {:?}, closing", UDP_TTL); quit.cancel(); break; } _ = packet_received.notified() => { // Reset timeout on packet activity } } } ``` -------------------------------- ### Run benchmarks with cargo Source: https://github.com/dndx/phantun/blob/main/_autodocs/README.md Execute the project benchmarks by enabling the benchmark feature. ```bash cargo bench --features benchmark ``` -------------------------------- ### Build Phantun Docker Image Source: https://github.com/dndx/phantun/blob/main/docker/README.md Build the Phantun Docker image using the provided Dockerfile. This command tags the image as 'phantun'. ```sh docker build -t phantun -f docker/Dockerfile . ``` -------------------------------- ### Stack::connect Source: https://github.com/dndx/phantun/blob/main/_autodocs/types.md Initiates a connection to a remote address. ```APIDOC ### Method `connect(&mut self, addr: SocketAddr) -> Option` ### Description Attempts to connect to the specified remote address. Returns the connected Socket if successful, otherwise None. ``` -------------------------------- ### Server with Handshake Packet Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Run the server using a specific handshake packet file. ```bash /usr/local/bin/phantun_server \ --local 4567 \ --remote 127.0.0.1:1234 \ --handshake-packet /etc/phantun/server_greeting.bin ``` -------------------------------- ### Configure IPv4 Forwarding Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Enable IPv4 forwarding in /etc/sysctl.conf. ```bash net.ipv4.ip_forward = 1 ``` -------------------------------- ### listen(port: u16) Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Registers a port on which the stack should accept incoming TCP connections. Multiple calls can be made to register multiple ports. ```APIDOC ## listen(port: u16) ### Description Registers a port on which the stack should accept incoming TCP connections. When a SYN packet is received on a registered port, the stack initiates the server-side TCP handshake. ### Parameters - **port** (u16) - Required - Port number to listen on. ### Example ```rust stack.listen(8080); ``` ``` -------------------------------- ### Stack::new Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Creates a new TCP stack instance with the specified TUN interfaces and local IP addresses. ```APIDOC ## Stack::new ### Description Creates a new TCP stack with the given TUN interfaces and local IP addresses. This constructor automatically spawns background reader tasks for each provided TUN interface to handle incoming packets. ### Signature `pub fn new(tun: Vec, local_ip: Ipv4Addr, local_ip6: Option) -> Stack` ### Parameters - **tun** (`Vec`) - Required - Array of TUN interface objects. Multiple objects enable Multiqueue TUN support. - **local_ip** (`Ipv4Addr`) - Required - IPv4 address for outgoing connections and server-side reception. - **local_ip6** (`Option`) - Optional - Optional IPv6 address for the stack. ### Returns - `Stack` - A new Stack object ready to accept or initiate connections. ### Example ```rust use tokio_tun::TunBuilder; use fake_tcp::Stack; use std::net::Ipv4Addr; #[tokio::main] async fn main() { let tun = TunBuilder::new() .name("tun0") .address(Ipv4Addr::new(192, 168, 1, 1)) .destination(Ipv4Addr::new(192, 168, 1, 2)) .up() .build() .unwrap(); let mut stack = Stack::new( vec![tun], Ipv4Addr::new(192, 168, 1, 1), None ); } ``` ``` -------------------------------- ### Configure --tun interface name Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Sets the name of the TUN interface. Defaults to an empty string, allowing the kernel to auto-select. ```text --tun ``` -------------------------------- ### Refactor IPv6 Configuration to Avoid Panics Source: https://github.com/dndx/phantun/blob/main/_autodocs/errors.md Compares the current code that panics on IPv6 configuration failure with a hypothetical approach that handles errors gracefully. ```rust // Current code (panics): assign_ipv6_address(tun[0].name(), tun_local6.unwrap(), tun_peer6.unwrap()); // Better approach (hypothetical): if let Err(e) = assign_ipv6_address_checked(tun[0].name(), tun_local6, tun_peer6) { eprintln!("Failed to configure IPv6: {}", e); // Continue with IPv4-only or fail gracefully } ``` -------------------------------- ### Configure IPv6 Forwarding Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Enable IPv6 forwarding for systems using IPv6. ```bash net.ipv6.conf.all.forwarding = 1 ``` -------------------------------- ### Register listening ports with listen Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Registers multiple ports for the stack to accept incoming TCP connections. Panics if the same port is registered more than once. ```rust stack.listen(8080); stack.listen(8081); ``` -------------------------------- ### Configure --remote address Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Specifies the destination IP or hostname and port for UDP packet forwarding. Hostname resolution occurs at startup. ```text -r, --remote ``` -------------------------------- ### Import library utilities and constants Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/phantun-lib.md Common import pattern used by client.rs and server.rs to access shared library functionality. ```rust use phantun::utils::{new_udp_reuseport, udp_recv_pktinfo, assign_ipv6_address}; use phantun::UDP_TTL; ``` -------------------------------- ### connect(addr: SocketAddr) -> Option Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Initiates an outgoing TCP connection to a remote address. ```APIDOC ## connect(addr: SocketAddr) -> Option ### Description Initiates an outgoing TCP connection to a remote address by performing a three-way handshake. It includes retry logic with a timeout mechanism. ### Parameters - **addr** (SocketAddr) - Required - Remote address to connect to, including IP and port. ### Returns - **Option** - Returns Some(Socket) if the connection succeeds, or None if the connection fails after retries. ### Example ```rust let remote = "203.0.113.1:4567".parse().unwrap(); if let Some(socket) = stack.connect(remote).await { // Connection established } ``` ``` -------------------------------- ### Configure Server NAT with iptables Source: https://github.com/dndx/phantun/blob/main/README.md Use these iptables and ip6tables commands on the server to DNAT the TCP port. Replace eth0 with your physical interface and 4567 with the Phantun server port. ```bash iptables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination 192.168.201.2 ip6tables -t nat -A PREROUTING -p tcp -i eth0 --dport 4567 -j DNAT --to-destination fcc9::2 ``` -------------------------------- ### Stack::new constructor signature Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md The signature for initializing a new TCP stack with TUN interfaces and IP addresses. ```rust pub fn new( tun: Vec, local_ip: Ipv4Addr, local_ip6: Option ) -> Stack ``` -------------------------------- ### Configure Client NAT with iptables Source: https://github.com/dndx/phantun/blob/main/README.md Use these iptables and ip6tables commands on the client to enable masquerade. Replace eth0 with your actual physical interface name. ```bash iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE ``` -------------------------------- ### Initiate outgoing connections with connect Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Initiates a TCP three-way handshake to a remote address. Returns Some(Socket) on success or None if retries are exhausted. ```rust let remote = "203.0.113.1:4567".parse().unwrap(); if let Some(socket) = stack.connect(remote).await { socket.send(b"Hello").await; let mut buf = [0u8; 1500]; if let Some(size) = socket.recv(&mut buf).await { println!("Received: {:?}", &buf[..size]); } } else { eprintln!("Connection failed"); } ``` -------------------------------- ### Handle Connection Refused Error Source: https://github.com/dndx/phantun/blob/main/_autodocs/errors.md Handles the Option::None result from Stack::connect() when the TCP three-way handshake fails. ```text ERROR: "Fake TCP connection to 203.0.113.1:4567 failed, emphemeral port number exhausted" ``` ```rust match stack.connect(remote_addr).await { Some(socket) => { // Connection established } None => { eprintln!("Failed to connect to {}", remote_addr); // Retry, try alternate server, or fail gracefully } } ``` -------------------------------- ### accept() -> Socket Source: https://github.com/dndx/phantun/blob/main/_autodocs/api-reference/fake-tcp-stack.md Blocks until an incoming TCP connection is established and returns the accepted socket. ```APIDOC ## accept() -> Socket ### Description Blocks until an incoming TCP connection is established. This method polls a receiver channel populated by reader tasks after the three-way handshake completes. ### Returns - **Socket** - A new socket representing an established connection with a remote peer. ### Example ```rust let socket = stack.accept().await; ``` ``` -------------------------------- ### Set cap_net_admin capability Source: https://github.com/dndx/phantun/blob/main/README.md Grant the necessary network administration capability to Phantun binaries to allow execution as a non-root user. ```bash sudo setcap cap_net_admin=+pe phantun_server sudo setcap cap_net_admin=+pe phantun_client ``` -------------------------------- ### Configure --local port Source: https://github.com/dndx/phantun/blob/main/_autodocs/configuration.md Specifies the TCP port for incoming Phantun Client connections. This is required for the fake TCP tunnel. ```text -l, --local ```