• Rust 39.2%
  • Kotlin 32.2%
  • Shell 12.7%
  • Python 10.7%
  • JavaScript 2.6%
  • Other 2.6%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Claude Code 878cefd970
All checks were successful
Claims ledger / Every README claim has a test (push) Successful in 3s
Android CI / Lint (push) Successful in 1m47s
Android CI / Unit Tests (push) Successful in 2m29s
Android CI / Build Debug APK (push) Successful in 3m10s
Nightly (deep tunnel, platforms, upgrade) / Deep tunnel suite (integrity, failure, performance, upgrade) (push) Successful in 6m16s
Nightly (deep tunnel, platforms, upgrade) / Linux distro matrix (real tunnel per distro) (push) Successful in 5m10s
Nightly (deep tunnel, platforms, upgrade) / Windows client executed (wine) (push) Successful in 3m8s
Nightly (deep tunnel, platforms, upgrade) / Tunnel e2e on arm64 (native) (push) Successful in 5m13s
Android emulator (real app, real internet) / Real app on emulators (API 26 + 34 + 36) (push) Successful in 27m11s
app: long-press the token box to make a new WiFi/Bluetooth token (refused while tethering, confirm dialog), FAQ updated; unit tests
2026-11-09 16:45:44 -08:00
.claude ci: use github.com URL for dtolnay/rust-toolchain (not mirrored on data.forgejo.org) 2026-09-25 09:04:50 -07:00
.forgejo ci: prefetch-gradle falls back to a public mirror, accepted only if sha256 equals Gradle's official .sha256 (GitHub asset 504s persisted through 8 retries) 2026-11-08 01:44:56 -08:00
.github/workflows ci(windows): Windows MSI e2e on our own Windows VM (Forgejo runner windows-x86_64); GitHub Windows jobs split into a workflow_dispatch-only fallback [skip ci] 2026-10-30 16:36:06 -07:00
android app: long-press the token box to make a new WiFi/Bluetooth token (refused while tethering, confirm dialog), FAQ updated; unit tests 2026-11-09 16:45:44 -08:00
ci macOS support follows Apple: every patched macOS (15+), Apple silicon + Intel universal pkg, target 15.0; CI xcode-27 + macos-26-intel + macos-15 (reverts the arm64/26-only restriction) 2026-10-30 12:33:36 -07:00
desktop fmt: split the poison-tolerant snapshot() chain (rustfmt chain_width, Format Check run 681) 2026-11-09 08:49:38 -08:00
docs app: long-press the token box to make a new WiFi/Bluetooth token (refused while tethering, confirm dialog), FAQ updated; unit tests 2026-11-09 16:45:44 -08:00
openwrt 0.9.2: installers, winget manifest, README and docs point at errant.solutions/download or the public GitHub repo, never the private git host; CI check (claims workflow + release.yml over every built asset) fails if canutethegreat.com or forgejo appears in anything shipped 2026-10-21 19:15:48 -07:00
protocol ETPH Free + Pro (0.9.0): one-time Play purchase etph_pro_lifetime, enforced on the phone 2026-10-20 16:38:41 -07:00
scripts v0.9.0 prep: FreeBSD rc.d service returns at once over ssh (daemon -f; VM test: rc.d start timed out), VM download check ignores fetch progress; release no longer waits for macOS (ships in 0.9.x; GitHub desktop-native back to manual dispatch only so a tag can't email the owner); DESKTOP.md: macOS/pfSense/OPNsense marked as coming; CHANGELOG 0.9.0: AOA, USB in every mode, router names, Windows MSI, FreeBSD pkgs; router-usb-realphone.sh: CPUS/DL_URL slow-router stand-in, stops crystalcave's adb-server.service unit for the ADB-route test 2026-10-20 20:44:29 -07:00
store 0.9.2: installers, winget manifest, README and docs point at errant.solutions/download or the public GitHub repo, never the private git host; CI check (claims workflow + release.yml over every built asset) fails if canutethegreat.com or forgejo appears in anything shipped 2026-10-21 19:15:48 -07:00
.editorconfig Release v0.4.0: Complete Bluetooth, token auth, auto-reconnect, mDNS, and profiles 2025-10-27 22:16:28 -07:00
.gitignore 0.9.2: installers, winget manifest, README and docs point at errant.solutions/download or the public GitHub repo, never the private git host; CI check (claims workflow + release.yml over every built asset) fails if canutethegreat.com or forgejo appears in anything shipped 2026-10-21 19:15:48 -07:00
BUILD_SUCCESS.md e2e: 20 parallel downloads by name through the phone core (stub DNS server, A+AAAA like glibc) in the desktop and emulator e2e; docs: DEVELOPMENT.md roadmap matches what shipped (root mode removed, Wi-Fi TLS shipped), desktop config file documented, historical docs marked 2026-10-24 05:35:56 -07:00
BUILD_VERIFICATION.md e2e: 20 parallel downloads by name through the phone core (stub DNS server, A+AAAA like glibc) in the desktop and emulator e2e; docs: DEVELOPMENT.md roadmap matches what shipped (root mode removed, Wi-Fi TLS shipped), desktop config file documented, historical docs marked 2026-10-24 05:35:56 -07:00
CHANGELOG.md 0.9.3 (Android versionCode 15): dark-mode follow-system release for Google Play internal (release-play-6); desktop/doc version claims follow (check-claims) 2026-10-30 21:29:24 -07:00
CI-TRIGGERS.md docs: CI-TRIGGERS.md without the forge product name (claims check forbids it in public docs); doc-only, no code change 2026-11-06 09:36:21 -08:00
CODE_OF_CONDUCT.md Release v0.4.0: Complete Bluetooth, token auth, auto-reconnect, mDNS, and profiles 2025-10-27 22:16:28 -07:00
config.example.toml gui: dark mode and auto-reconnect survive a restart ([gui] dark_mode + default.auto_reconnect in config.toml, written on toggle, read at startup); the root config.example.toml described sections the client never read and is now a checked copy of desktop/config.example.toml 2026-10-18 14:21:23 -07:00
CONTRIBUTING.md Release v0.4.0: Complete Bluetooth, token auth, auto-reconnect, mDNS, and profiles 2025-10-27 22:16:28 -07:00
IMPLEMENTATION_SUMMARY.md fix(usb): use adb forward, not adb reverse; e2e emulates adb direction 2026-10-16 17:10:14 -07:00
LICENSE Release v0.4.0: Complete Bluetooth, token auth, auto-reconnect, mDNS, and profiles 2025-10-27 22:16:28 -07:00
PROJECT_SUMMARY.md fix(usb): use adb forward, not adb reverse; e2e emulates adb direction 2026-10-16 17:10:14 -07:00
QUICKSTART.md fix(usb): use adb forward, not adb reverse; e2e emulates adb direction 2026-10-16 17:10:14 -07:00
README.md 0.9.3 (Android versionCode 15): dark-mode follow-system release for Google Play internal (release-play-6); desktop/doc version claims follow (check-claims) 2026-10-30 21:29:24 -07:00
STATUS.md 0.9.3 (Android versionCode 15): dark-mode follow-system release for Google Play internal (release-play-6); desktop/doc version claims follow (check-claims) 2026-10-30 21:29:24 -07:00
V0.3.0_IMPLEMENTATION.md e2e: 20 parallel downloads by name through the phone core (stub DNS server, A+AAAA like glibc) in the desktop and emulator e2e; docs: DEVELOPMENT.md roadmap matches what shipped (root mode removed, Wi-Fi TLS shipped), desktop config file documented, historical docs marked 2026-10-24 05:35:56 -07:00
WIFI_MODE_IMPLEMENTATION.md e2e: 20 parallel downloads by name through the phone core (stub DNS server, A+AAAA like glibc) in the desktop and emulator e2e; docs: DEVELOPMENT.md roadmap matches what shipped (root mode removed, Wi-Fi TLS shipped), desktop config file documented, historical docs marked 2026-10-24 05:35:56 -07:00

ET Phone Home

A modern, open-source tethering solution for Android with companion apps for Windows and Linux - an alternative to PDANet and EasyTether.

Your computer uses the phone's internet over USB, WiFi or Bluetooth. No root, no VPN on the phone, and the phone keeps its own internet the whole time.

Website and downloads: https://errant.solutions/etphonehome/ (latest release files: Releases).

Google Play: the Android app is coming to Google Play as Errant Solutions ETPH (ETPH = ET Phone Home, app id solutions.errant.etph); until it is live, install the APK from the releases. Since 0.7.0 the app id is solutions.errant.etph (it was com.etphonehome), so the new app installs next to an old copy instead of updating it, and shows a notice with a button to the old app's App info page so you can uninstall it.

License: MIT Platform

🚀 Quick Start

Linux:

sudo ./scripts/quick-start-linux.sh

Windows (PowerShell as Administrator):

.\scripts\quick-start-windows.ps1

See the Setup Guide for detailed instructions.

✨ Features

Free and Pro

One app, two tiers. Free shares the phone's internet over USB with one computer, with no speed cap and no time limit; you start and stop it on the phone. ETPH Pro is a one-time in-app purchase in the Google Play app (US$15, local prices elsewhere; no subscription) that adds Wi-Fi and Bluetooth, routers, several computers and routers, auto-start when the computer asks plus waiting for it to come back (auto-reconnect), and a data usage history. The phone enforces the split: desktops and routers never need a licence of their own, and when something needs Pro the phone says so in the handshake, so the client prints "Pro required on the phone". How purchases are checked (no server): docs/pro.md.

Free ETPH Pro
USB to one computer, unlimited speed and time yes yes
Wi-Fi (TLS 1.3) and Bluetooth - yes
Routers (OpenWrt / GL.iNet uplink) - yes
Several computers and routers one computer yes
Auto-start on plug-in, keeps waiting after a disconnect start/stop by hand yes
Data usage per computer/router and kind of traffic live numbers only yes

Current Features (v0.9.3)

  • ✅ Free: USB to one computer - no speed cap and no time limit; a second computer or a router is refused by the phone with "Pro required on the phone", and the phone lists paired computers with Forget

  • ✅ ETPH Pro is enforced by the phone - one-time Google Play purchase (Play Billing, acknowledged, restored on reinstall or a new phone, pending purchases and refunds handled); the handshake tells computers and routers whether the phone has Pro, nothing is ever licensed on them

  • ✅ Auto-start on plug-in (Pro) - the computer asks the phone over USB debugging to start sharing (once per plug-in); the phone keeps waiting for the computer after a disconnect

  • ✅ Data usage (Pro) - history per computer/router (today, this month, 30 days) and by kind of traffic (web, DNS, email, calls...), kept on the phone only

  • ✅ Real internet for the computer, no root - the app relays the computer's TCP, UDP (DNS included) and ping traffic through ordinary phone sockets (a userspace relay). Verified in CI against public HTTPS and on a real phone (Samsung, Android 13)

  • ✅ The phone keeps its internet - no phone VPN is used, so the phone's own apps are never affected

  • ✅ USB Tethering - via adb forward, fastest and most reliable

  • ✅ USB without Developer options - routers and Linux computers switch the phone into USB accessory mode (Android Open Accessory); Android asks "Open Errant Solutions ETPH to handle ...?", tap OK, no USB debugging needed. Falls back to adb when the phone's ETPH is older. Verified on a real phone (Samsung, Android 13) with the official OpenWrt arm64 image (scripts/router-usb-realphone.sh); CI covers the switch, the stream preamble and the phone's side with fakes

  • ✅ USB works in every mode - computers and routers on the cable are served whether the app was started in USB, Wi-Fi or Bluetooth mode

  • ✅ WiFi Tethering (Pro) - token-authenticated and encrypted by default (TLS 1.3, certificate pinned to the pairing token, fails closed)

  • ✅ Bluetooth Tethering (Pro) - RFCOMM, Linux (BlueZ) desktop only; the Windows client has no Bluetooth. Verified with real internet on a real phone (Samsung, Android 13); CI has no Bluetooth radio, so it checks the session code and that app and desktop agree on the service

  • ✅ Cross-Platform desktop - Linux, Windows (MSI with a tray app and a service), every macOS version Apple still patches, Apple silicon and Intel (macOS 15+ today; dropped when Apple stops patching; .pkg, universal; the installer refuses older macOS; menu-bar app, CLI and a launchd service; utun tunnel, DNS through scutil) and FreeBSD 14/15 (pkg), Linux GUI. The macOS package is installed and tested in CI on macOS 27 and 15 (Apple silicon) and macOS 26 (Intel) with real internet through the phone core

  • ✅ DNS set up for you - the desktop points DNS for the tunnel at the phone's DNS server (systemd-resolved on Linux, verified in CI; netsh on Windows, asserted in the Windows e2e (packaging/windows/e2e.ps1))

  • ✅ Live statistics on the phone - connected desktop, data each way, open connections, uptime; the status only says "connected" once a desktop really is

  • ✅ Traffic filter - a connection profile's allow/block rules are applied on the computer and sent to the phone, which enforces them on the connections it opens

  • ✅ Auto-Reconnect - exponential backoff retry

  • ✅ mDNS Discovery, IP Discovery (ADB), Connection Profiles

  • ✅ Open Protocol - documented binary protocol, shared test vectors between the Rust and Kotlin sides

  • ✅ Routers (OpenWrt, GL.iNet) (Pro) - the phone becomes a router's internet (WAN) for every device behind it, over USB (built-in ADB host, no adb package) or Wi-Fi: packages for OpenWrt 24.10 (opkg, also GL.iNet 4.x) and 25.x (apk) on aarch64, armv7, mips, mipsel and x86_64, a normal network interface (proto etph: firewall zones, metrics, mwan3 failover) and a LuCI page with status and pairing. Tested in CI on real OpenWrt 24.10 and 25.12 VMs. See docs/OPENWRT.md

  • ✅ Firewalls (OPNsense, pfSense CE) (Pro) - the phone as an interface of the firewall (etph0) with its own gateway, for WAN failover in a gateway group or as the only uplink: the OPNsense plugin os-etph and the pfSense package pfSense-pkg-etph, each with a page under Interfaces (settings, phone status, ETPH Pro), a service, and the client from the FreeBSD packages. Tested in CI on real OPNsense 26.7 and pfSense CE 2.7.2 VMs: a LAN client keeps HTTPS through the phone when the primary WAN fails. See docs/DESKTOP.md

Planned Features

  • 🔲 Root mode (kernel NAT on rooted phones). It is not in the app: an earlier, unreachable and wrongly designed implementation was removed in v0.6.0
  • 🔲 Bluetooth in the Windows client
  • 🔲 IPv6 through the tunnel (IPv4 only today)
  • 🔲 Several computers at the same time (Pro pairs several, but the phone serves one at a time)

📋 Requirements

Android Device

  • Android 8.0+ (API Level 26+)
  • For USB: nothing to enable with routers and Linux computers (USB accessory link); USB debugging (Developer options) for Windows and for computers that use the adb tool
  • No root and no VPN permission needed

Desktop Computer

Linux:

  • Root/sudo access
  • TUN kernel module (usually built-in)
  • ADB (Android Debug Bridge)
  • Any distro with glibc 2.31 or newer (the release binary is linked against glibc 2.31 and carries its own libdbus); tested nightly with a real tunnel on Debian 11/12/13, Ubuntu 20.04/22.04/24.04, Fedora, Arch and openSUSE Tumbleweed (x86_64), plus the full tunnel test on arm64

Windows:

  • Administrator privileges
  • Nothing to install besides ETPH: the Wintun driver (wintun.dll, signed by WireGuard LLC) comes with the installer and the zip (the client uses Wintun, not TAP-Windows)
  • ADB (Android Debug Bridge)

🏗️ Project Structure

etphonehome/
├── android/              # Android application (Kotlin)
│   └── app/src/main/
│       ├── java/com/etphonehome/
│       │   ├── MainActivity.kt           # Main UI (status + live statistics)
│       │   └── service/TetherService.kt  # Foreground service: USB/WiFi/Bluetooth listeners
│       └── res/                          # Android resources
├── android/core/         # Platform-independent core (plain Kotlin/JVM)
│   ├── src/main/kotlin/com/etphonehome/
│   │   ├── relay/        # Userspace TCP/UDP/ICMP relay
│   │   ├── session/      # Handshake + per-desktop session, TLS/plaintext detection
│   │   ├── tls/          # Cert-pinned TLS 1.3 server (Bouncy Castle)
│   │   ├── protocol/     # Wire protocol
│   │   └── filter/       # Traffic filter
│   └── standin/          # The same core as a JVM program (CI end-to-end test)
│
├── desktop/              # Desktop applications (Rust)
│   ├── common/           # Shared library
│   │   └── src/
│   │       ├── protocol.rs      # Protocol implementation
│   │       ├── client.rs        # Connection client
│   │       └── tun_interface.rs # TUN interface manager
│   ├── linux/            # Linux-specific client
│   └── windows/          # Windows-specific client
│
├── protocol/             # Protocol specification
│   └── PROTOCOL.md       # Binary protocol documentation
│
├── docs/                 # Documentation
│   ├── BUILD.md          # Build instructions
│   ├── SETUP.md          # Setup and usage guide
│   ├── DEVELOPMENT.md    # Developer guide
│   └── FAQ.md            # Frequently asked questions
│
└── scripts/              # Helper scripts
    ├── quick-start-linux.sh      # Linux quick start
    └── quick-start-windows.ps1   # Windows quick start

🔧 Building from Source

Prerequisites

For Android:

  • Android Studio (latest)
  • JDK 17+
  • Android SDK API 36 (minSdk 26)

For Desktop:

  • Rust (latest stable)
  • Platform build tools (see BUILD.md)

Build Android App

cd android
./gradlew assembleDebug

# Install on device
adb install app/build/outputs/apk/debug/app-debug.apk

Build Desktop Client

Linux:

cd desktop
cargo build --release -p etphonehome-linux
sudo cp target/release/etphonehome /usr/local/bin/

Windows:

cd desktop
cargo build --release -p etphonehome-windows

See BUILD.md for detailed build instructions.

📖 How It Works

ET Phone Home uses different approaches based on what's available:

Userspace relay (no root, no phone VPN)

┌───────────────────────┐                          ┌──────────────────┐
│  Desktop              │                          │  Android phone   │
│                       │  IP packets in protocol  │                  │
│  apps → TUN (etph0) ──┼──── messages over ──────→│  relay: one real │──→ phone's
│        default route  │  USB / WiFi(TLS) / BT    │  socket per flow │    own network
│                    ←──┼──────────────────────────┼──  (TCP/UDP/ICMP)│←── (mobile/WiFi)
└───────────────────────┘                          └──────────────────┘
  1. Desktop: a TUN interface (etph0, 10.0.0.1) becomes a default route; DNS for it points at the DNS server the phone announces
  2. Transport: the desktop's IP packets travel to the phone over USB (adb forward), WiFi (TLS 1.3) or Bluetooth
  3. Phone: the relay terminates each TCP connection and UDP flow itself and opens an ordinary socket to the same destination, exactly like any app would; replies are turned back into IP packets for the desktop
  4. The phone's own traffic is untouched - nothing is captured, so the phone keeps its internet

Connection Methods

USB (Recommended - Fastest):

  • Uses ADB port forwarding: adb forward tcp:8888 tcp:8888
  • Android app listens on localhost:8888
  • Desktop connects to localhost:8888 (tunneled via ADB)
  • Most reliable and fastest
  • Charges device while tethering

WiFi (Wireless Convenience):

  • Android creates server socket on WiFi interface
  • Desktop connects directly to Android's WiFi IP
  • No cables required
  • Slightly higher latency (+10-25ms)
  • Token authentication, and TLS 1.3 by default (pinned to the token; the app refuses plaintext unless you switch "Require encryption" off, then use --no-tls)
  • Use discover-wifi command for automatic discovery

Bluetooth (Low Power):

  • RFCOMM via BlueZ on Linux (the app's own service UUID; BlueZ finds its channel over SDP)
  • The Windows client does not support Bluetooth yet (use USB or WiFi there)
  • Token authentication for security
  • Lower power consumption than WiFi
  • Slowest connection method (typical Bluetooth speeds)

🎯 Usage Examples

Basic USB Tethering

On Android:

  1. Enable USB debugging
  2. Connect to computer via USB
  3. Open ET Phone Home app
  4. Tap "Start Tethering"

On Desktop:

# Set up ADB forwarding
sudo etphonehome setup-adb

# Connect
sudo etphonehome usb

WiFi Tethering

Method 1: Automatic Discovery (Recommended)

On Android:

  1. Open ET Phone Home app
  2. Select "WiFi" mode
  3. Tap "Start Tethering"
  4. Note the WiFi IP and Auth Token displayed

On Desktop:

# Discover Android devices on local network
sudo etphonehome discover-wifi

# Connect to discovered device (use token from Android app)
sudo etphonehome wifi --host 192.168.1.100 --token AbC123XyZ4567890

Method 2: ADB Discovery (USB connected)

# Discover Android WiFi IP via ADB
sudo etphonehome discover-ip
# Output: ✓ Android WiFi IP: 192.168.1.100

# Connect using discovered IP and token from Android app
sudo etphonehome wifi --host 192.168.1.100 --token AbC123XyZ4567890

Method 3: Manual IP Entry

Find Android's WiFi IP in Settings → About → Status, then:

sudo etphonehome wifi --host 192.168.1.100 --token AbC123XyZ4567890

Bluetooth Tethering

On Android:

  1. Open ET Phone Home app
  2. Select "Bluetooth" mode
  3. Tap "Start Tethering"
  4. Note the Device Name and Auth Token displayed (Android does not let apps show the phone's Bluetooth address; the name works instead)

On Desktop (Linux):

# Pair device first (one-time setup)
bluetoothctl
# > pair XX:XX:XX:XX:XX:XX
# > trust XX:XX:XX:XX:XX:XX
# > exit

# Connect: --address takes the phone's name as paired, or its address
sudo etphonehome bluetooth --address "Galaxy Note20 Ultra 5G" --token AbC123XyZ4567890

On Desktop (Windows): Bluetooth is not supported by the Windows client yet; use USB or WiFi.

Connection Profiles

Save frequently used connections for quick access:

# Save a WiFi profile
etphonehome save-profile my-home-wifi --type wifi --host 192.168.1.100 --description "Home WiFi connection"

# Save a Bluetooth profile
etphonehome save-profile my-phone-bt --type bluetooth --address XX:XX:XX:XX:XX:XX

# List all profiles
etphonehome list-profiles

# Connect using a profile
sudo etphonehome connect my-home-wifi

# Delete a profile
etphonehome delete-profile my-home-wifi

Profiles live in ~/.config/etphonehome/config.toml. sudo etphonehome connect ... reads the invoking user's file (not root's), so profiles saved without sudo are found. Use --config <file> or ETPHONEHOME_CONFIG=<file> to pick another file. WiFi profiles use auth.wifi_token and Bluetooth profiles auth.bluetooth_token from that file; a profile's [profiles.filter] rules are applied to outgoing traffic on the computer and sent to the phone, which enforces them on the connections it relays. A profile whose enabled filter has a rule with an address or port spec that doesn't parse is refused before connecting, so a typo can't leave a BLOCK rule doing nothing.

Auto-Reconnect

Enable automatic reconnection on connection drops:

# WiFi with auto-reconnect (infinite retries)
sudo etphonehome wifi --host 192.168.1.100 --token XXX --reconnect

# With maximum retry limit
sudo etphonehome wifi --host 192.168.1.100 --token XXX --reconnect --max-retries 10

# USB with auto-reconnect
sudo etphonehome usb --reconnect

Auto-reconnect is off unless --reconnect is given for usb/wifi/bluetooth; connect <profile> follows the profile file's default.auto_reconnect and accepts --reconnect=false to override it. Backoff is 1, 2, 4 ... 60 seconds. Ctrl-C sends a Disconnect to the phone and exits.

Custom Configuration

# Custom port
etphonehome usb --port 9999

# Custom interface name
etphonehome usb --interface mytun0

See SETUP.md for more usage examples.

🐛 Troubleshooting

Connection fails:

# Check ADB connection
adb devices

# Check ADB forwarding
adb forward --list

# Check logs
adb logcat -s ETPhoneHome:V

TUN interface issues (Linux):

# Load TUN module
sudo modprobe tun

# Check if loaded
lsmod | grep tun

Windows TUN adapter:

  • The client uses the Wintun driver, which comes with ETPH (wintun.dll next to etphonehome.exe in C:\Program Files\ETPH); if you copy etphonehome.exe elsewhere, copy wintun.dll with it
  • Run as Administrator

See FAQ.md for more troubleshooting help.

🤝 Contributing

Contributions are welcome! Please see DEVELOPMENT.md for:

  • Development setup
  • Architecture overview
  • Coding standards
  • How to contribute

📚 Documentation

🔒 Security

  • USB mode: the app's port is bound to the phone's loopback, reachable only through adb forward over the cable
  • WiFi mode: token authentication plus TLS 1.3 by default; both sides derive an Ed25519 key from the pairing token and pin it, so a wrong token fails the handshake and there is no plaintext fallback
  • Bluetooth mode: token authentication over a paired (link-encrypted) RFCOMM connection
  • No phone VPN: the phone's own traffic is never captured or inspected
  • Open Source: All code is auditable under MIT license
  • No telemetry: No data collection or tracking

See FAQ.md for more security information.

🆚 Comparison

Feature ET Phone Home PDANet EasyTether Native Tethering
Price Free Freemium Paid Free
Open Source ✅ ❌ ❌ N/A
No Root ✅ ✅ ✅ ✅
USB ✅ ✅ ✅ ✅
WiFi ✅ ✅ ✅ ✅
Bluetooth ✅ (Linux desktop) ✅ ❌ ✅
Encrypted WiFi link ✅ TLS 1.3 ❌ ❌ WPA
Token Auth ✅ ❌ ❌ N/A
Auto-Reconnect ✅ Unknown Unknown N/A
Connection Profiles ✅ Unknown Unknown N/A
mDNS Discovery ✅ ❌ ❌ N/A
Traffic leaves from phone app sockets (not the hotspot path) ✅ ✅ ✅ ❌
Phone keeps its own internet ✅ ✅ ✅ ✅
Desktop GUI ✅ (Linux) ✅ ✅ N/A
macOS client ✅ ✅ ✅ ✅

📄 License

This project is licensed under the MIT License.

You are free to use, modify, and distribute this software for any purpose, including commercial use. See the LICENSE file for details.

🙏 Acknowledgments

  • Inspired by PDANet and EasyTether
  • Built with Rust and Kotlin
  • Uses tun-rs for TUN interface

📞 Support


Note: Current version is v0.9.3 (Beta). Downloads (Linux/Windows/macOS/FreeBSD clients, Linux GUI, Android APK, OpenWrt router packages, OPNsense plugin, pfSense package): Releases. See the roadmap in FAQ.md for planned features.