Skip to content

Auto-discovery of Windows machines on LAN via mDNS + port scan #13

@CREVIOS

Description

@CREVIOS

Overview

Automatically discover Windows machines on the local network that have RDP enabled. Show them in a "Nearby Machines" section on the connection grid — one click to connect.

Architecture

┌──── Local Network ──────────────────────────────────────────┐
│                                                              │
│  Drift Client                                                │
│  ┌────────────────────────────────────────────────┐          │
│  │  Discovery Engine                               │          │
│  │                                                 │          │
│  │  1. mDNS query (_rdp._tcp, _smb._tcp)          │          │
│  │     → resolves hostnames + IPs                  │          │
│  │                                                 │          │
│  │  2. ARP table scan (ip neigh / arp -a)          │          │
│  │     → all devices on subnet                     │          │
│  │                                                 │          │
│  │  3. TCP probe port 3389 on discovered IPs       │          │
│  │     → confirms RDP is listening                 │          │
│  │                                                 │          │
│  │  4. NetBIOS name query (UDP 137)                │          │
│  │     → resolves Windows hostname                 │          │
│  │                                                 │          │
│  │  Results: [                                     │          │
│  │    { ip: "192.168.1.50", name: "DESKTOP-ABC",   │          │
│  │      os: "Windows 11", rdp: true },             │          │
│  │    { ip: "192.168.1.51", name: "SERVER-01",     │          │
│  │      os: "Windows Server 2022", rdp: true },    │          │
│  │  ]                                              │          │
│  └────────────────────────────────────────────────┘          │
│                                                              │
│  ┌─ 192.168.1.50 ─┐  ┌─ 192.168.1.51 ─┐  ┌─ 192.168.1.52 │
│  │ Windows 11      │  │ Windows Server  │  │ Linux (no RDP) │
│  │ RDP: 3389 open  │  │ RDP: 3389 open  │  │ RDP: closed    │
│  └─────────────────┘  └─────────────────┘  └────────────────┘
└──────────────────────────────────────────────────────────────┘

Implementation Plan

Step 1: mDNS service discovery

Use mdns-sd crate for mDNS/DNS-SD:

use mdns_sd::{ServiceDaemon, ServiceEvent};

let mdns = ServiceDaemon::new()?;
let receiver = mdns.browse("_smb._tcp.local.")?; // Windows machines often advertise SMB

while let Ok(event) = receiver.recv() {
    match event {
        ServiceEvent::ServiceResolved(info) => {
            // Got hostname + IP
            let ip = info.get_addresses().iter().next()?;
            let hostname = info.get_hostname();
            // TCP probe port 3389 to confirm RDP...
        }
        _ => {}
    }
}

Step 2: Subnet scan fallback

If mDNS doesn't find machines (common on enterprise networks):

  1. Get local IP and subnet mask
  2. ARP scan: read /proc/net/arp (Linux) or arp -a (macOS)
  3. TCP connect probe to port 3389 on each discovered IP
  4. Timeout: 500ms per probe, run 20 probes in parallel

Step 3: NetBIOS name resolution

For discovered IPs, query UDP port 137 to get the Windows hostname:

NBTSTAT query → "DESKTOP-ABC" (Workstation), "MYDOM" (Domain)

Step 4: UI — "Nearby Machines" section

Add a section above the saved connections grid:

┌─────────────────────────────────────────────────────┐
│  Nearby Machines                    🔄 Scanning...  │
│                                                     │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐          │
│  │ 💻        │  │ 🖥️        │  │ 💻        │          │
│  │ DESKTOP   │  │ SERVER-01│  │ WIN-PC   │          │
│  │ .168.1.50 │  │ .168.1.51│  │ .168.1.55│          │
│  │ [Connect] │  │ [Connect] │  │ [Connect] │          │
│  └──────────┘  └──────────┘  └──────────┘          │
│                                                     │
│  Saved Connections                                  │
│  ...                                                │
└─────────────────────────────────────────────────────┘

Step 5: Quick connect from discovery

  • Click "Connect" on a discovered machine → opens connection form pre-filled with IP
  • Or: direct connect with a credentials dialog (username + password only)
  • Save option: "Save this connection" after connecting

Step 6: Continuous background scan

  • Scan on app startup
  • Re-scan every 30 seconds (lightweight)
  • Cache results, show "last seen" timestamp
  • Settings: enable/disable auto-discovery

Files to create/modify

  • src-tauri/src/utils/discovery.rs — new module: mDNS + ARP + TCP probe + NetBIOS
  • src-tauri/src/commands/discovery.rs — Tauri commands: start_scan, get_results
  • src/components/connections/NearbyMachines.tsx — UI component
  • src/components/connections/ConnectionGrid.tsx — integrate NearbyMachines section
  • src/hooks/useDiscovery.ts — hook for scan state + results
  • src-tauri/Cargo.toml — add mdns-sd

Dependencies

  • mdns-sd = "0.11" — mDNS service discovery
  • TCP probing: already have tokio::net::TcpStream with timeout

Security considerations

  • Only scan the local subnet (don't scan external IPs)
  • Don't store discovered machine credentials
  • Respect network policies (some enterprise networks block mDNS/scans)
  • Settings toggle to disable scanning entirely

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestuiUser interface

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions