mirror of
https://github.com/CyberMind-FR/secubox-deb.git
synced 2026-07-29 17:37:13 +00:00
fix(eye-remote): Use usb1 (ECM) instead of usb0 for Linux hosts
The USB composite gadget creates two network interfaces: - usb0: RNDIS function (for Windows hosts) - usb1: ECM function (for Linux/Mac hosts via cdc_ether driver) Previously, both interfaces were configured with the same IP (10.55.0.2/30), causing asymmetric routing issues where packets received on usb1 could be replied via usb0. Fix: Configure only usb1 (ECM) since that's what Linux hosts use. Falls back to usb0 if usb1 is not present (e.g., single-function gadget). Changes: - secubox-otg-gadget.sh: Wait for and configure usb1 instead of usb0 - gadget-setup.sh: Same fix for eye-remote variant - agent/main.py: Update ensure_usb_network() to prefer usb1 - agent/network_debug.py: New debug script for USB network troubleshooting Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
980e0076c4
commit
48de2440b8
|
|
@ -26,6 +26,52 @@ from touch_handler import TouchHandler, create_touch_handler, Gesture
|
|||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def ensure_usb_network():
|
||||
"""Ensure USB network interface is configured for OTG connection.
|
||||
|
||||
The composite gadget creates two interfaces:
|
||||
- usb0: RNDIS (Windows compatible)
|
||||
- usb1: ECM (Linux/Mac compatible via cdc_ether driver)
|
||||
|
||||
Linux hosts use cdc_ether which maps to usb1.
|
||||
We configure only usb1 to avoid asymmetric routing issues.
|
||||
"""
|
||||
import subprocess
|
||||
import time
|
||||
|
||||
for attempt in range(30):
|
||||
# Prefer usb1 (ECM) for Linux hosts
|
||||
if Path("/sys/class/net/usb1").exists():
|
||||
try:
|
||||
subprocess.run(["/sbin/ip", "addr", "flush", "dev", "usb1"],
|
||||
capture_output=True, timeout=5)
|
||||
subprocess.run(["/sbin/ip", "addr", "add", "10.55.0.2/30", "dev", "usb1"],
|
||||
capture_output=True, timeout=5)
|
||||
subprocess.run(["/sbin/ip", "link", "set", "usb1", "up"],
|
||||
capture_output=True, timeout=5)
|
||||
log.info(f"usb1 (ECM) configured: 10.55.0.2/30 (attempt {attempt + 1})")
|
||||
return True
|
||||
except Exception as e:
|
||||
log.warning(f"Failed to configure usb1: {e}")
|
||||
# Fallback to usb0 (RNDIS) if usb1 not present
|
||||
elif Path("/sys/class/net/usb0").exists():
|
||||
try:
|
||||
subprocess.run(["/sbin/ip", "addr", "flush", "dev", "usb0"],
|
||||
capture_output=True, timeout=5)
|
||||
subprocess.run(["/sbin/ip", "addr", "add", "10.55.0.2/30", "dev", "usb0"],
|
||||
capture_output=True, timeout=5)
|
||||
subprocess.run(["/sbin/ip", "link", "set", "usb0", "up"],
|
||||
capture_output=True, timeout=5)
|
||||
log.info(f"usb0 (RNDIS) configured: 10.55.0.2/30 (attempt {attempt + 1})")
|
||||
return True
|
||||
except Exception as e:
|
||||
log.warning(f"Failed to configure usb0: {e}")
|
||||
time.sleep(1)
|
||||
|
||||
log.warning("No USB network interface found after 30 attempts")
|
||||
return False
|
||||
|
||||
# Default paths
|
||||
SOCKET_PATH = Path("/run/secubox-eye/metrics.sock")
|
||||
PID_FILE = Path("/run/secubox-eye/agent.pid")
|
||||
|
|
@ -359,6 +405,9 @@ async def main():
|
|||
format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
|
||||
)
|
||||
|
||||
# Ensure USB OTG network is configured
|
||||
ensure_usb_network()
|
||||
|
||||
# Parse args
|
||||
config_path = DEFAULT_CONFIG_PATH
|
||||
if len(sys.argv) > 1:
|
||||
|
|
|
|||
83
remote-ui/round/agent/network_debug.py
Normal file
83
remote-ui/round/agent/network_debug.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Configure USB network interface for OTG connection.
|
||||
|
||||
For Linux/Mac hosts: Only configure usb1 (ECM) to avoid routing issues.
|
||||
The composite gadget creates:
|
||||
- usb0: RNDIS (Windows compatible)
|
||||
- usb1: ECM (Linux/Mac compatible via cdc_ether driver)
|
||||
|
||||
Linux hosts use the cdc_ether driver which maps to usb1.
|
||||
Configuring both interfaces with the same IP causes asymmetric routing.
|
||||
|
||||
CyberMind - https://cybermind.fr
|
||||
Author: Gerald Kerma <gandalf@gk2.net>
|
||||
"""
|
||||
import subprocess
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
LOG = "/var/log/usb_network_debug.log"
|
||||
|
||||
|
||||
def log(msg: str) -> None:
|
||||
"""Log message to file and stdout."""
|
||||
with open(LOG, "a") as f:
|
||||
f.write(f"{time.strftime('%H:%M:%S')} {msg}\n")
|
||||
print(msg)
|
||||
|
||||
|
||||
def configure_interface(iface: str, ip: str) -> bool:
|
||||
"""Configure a USB network interface with IP address."""
|
||||
if not Path(f"/sys/class/net/{iface}").exists():
|
||||
return False
|
||||
|
||||
log(f"Configuring {iface} with {ip}")
|
||||
|
||||
# Flush existing addresses
|
||||
r = subprocess.run(["/sbin/ip", "addr", "flush", "dev", iface],
|
||||
capture_output=True, text=True)
|
||||
log(f" flush: rc={r.returncode}")
|
||||
|
||||
# Add IP address
|
||||
r = subprocess.run(["/sbin/ip", "addr", "add", ip, "dev", iface],
|
||||
capture_output=True, text=True)
|
||||
log(f" addr add: rc={r.returncode}")
|
||||
|
||||
# Bring interface up
|
||||
r = subprocess.run(["/sbin/ip", "link", "set", iface, "up"],
|
||||
capture_output=True, text=True)
|
||||
log(f" link up: rc={r.returncode}")
|
||||
|
||||
# Show final state
|
||||
r = subprocess.run(["ip", "addr", "show", iface], capture_output=True, text=True)
|
||||
log(f" state:\n{r.stdout}")
|
||||
|
||||
return r.returncode == 0
|
||||
|
||||
|
||||
def main() -> bool:
|
||||
"""Configure USB network interface."""
|
||||
log("=== USB Network Config Started ===")
|
||||
log("Linux/Mac hosts use ECM (usb1), Windows uses RNDIS (usb0)")
|
||||
|
||||
# Wait for usb1 (ECM) interface - this is what Linux hosts use
|
||||
for attempt in range(30):
|
||||
if Path("/sys/class/net/usb1").exists():
|
||||
log(f"usb1 (ECM) found at attempt {attempt + 1}")
|
||||
configure_interface("usb1", "10.55.0.2/30")
|
||||
log("=== USB Network Config Complete ===")
|
||||
return True
|
||||
time.sleep(1)
|
||||
|
||||
# Fallback to usb0 if usb1 doesn't appear (Windows host or single-function gadget)
|
||||
if Path("/sys/class/net/usb0").exists():
|
||||
log("usb1 not found, falling back to usb0 (RNDIS)")
|
||||
configure_interface("usb0", "10.55.0.2/30")
|
||||
return True
|
||||
|
||||
log("ERROR: No USB interfaces found after 30 seconds")
|
||||
return False
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
@ -214,17 +214,25 @@ gadget_up() {
|
|||
debug "Binding to UDC: ${udc}"
|
||||
echo "$udc" > UDC
|
||||
|
||||
# Wait for usb0 interface to appear
|
||||
# Wait for usb1 (ECM) interface to appear
|
||||
# Note: Composite gadget creates usb0 (RNDIS/Windows) and usb1 (ECM/Linux-Mac)
|
||||
# Linux hosts use cdc_ether driver which maps to usb1
|
||||
local retry=0
|
||||
while [[ ! -d /sys/class/net/usb0 ]] && [[ $retry -lt 10 ]]; do
|
||||
while [[ ! -d /sys/class/net/usb1 ]] && [[ $retry -lt 10 ]]; do
|
||||
sleep 0.5
|
||||
((retry++))
|
||||
done
|
||||
|
||||
if [[ -d /sys/class/net/usb0 ]]; then
|
||||
debug "Interface usb0 created"
|
||||
if [[ -d /sys/class/net/usb1 ]]; then
|
||||
debug "Interface usb1 (ECM) created"
|
||||
|
||||
# Configure IP on usb1 only (avoids asymmetric routing with same IP on both)
|
||||
ip addr flush dev usb1 2>/dev/null || true
|
||||
ip addr add 10.55.0.2/30 dev usb1
|
||||
ip link set usb1 up
|
||||
debug "usb1 configured: 10.55.0.2/30"
|
||||
else
|
||||
err "Interface usb0 did not appear after 5s"
|
||||
err "Interface usb1 did not appear after 5s"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
|
|
|||
|
|
@ -266,24 +266,26 @@ gadget_start() {
|
|||
log "Activation sur UDC: ${udc}"
|
||||
echo "$udc" > UDC
|
||||
|
||||
# Attendre que l'interface usb0 apparaisse
|
||||
# Attendre que l'interface usb1 (ECM) apparaisse
|
||||
# Note: Le gadget composite crée usb0 (RNDIS/Windows) et usb1 (ECM/Linux-Mac)
|
||||
# On configure usb1 car les hôtes Linux utilisent le driver cdc_ether (ECM)
|
||||
local retry=0
|
||||
while [[ ! -d /sys/class/net/usb0 ]] && [[ $retry -lt 10 ]]; do
|
||||
while [[ ! -d /sys/class/net/usb1 ]] && [[ $retry -lt 10 ]]; do
|
||||
sleep 0.5
|
||||
((retry++))
|
||||
done
|
||||
|
||||
if [[ -d /sys/class/net/usb0 ]]; then
|
||||
log "Interface usb0 créée"
|
||||
if [[ -d /sys/class/net/usb1 ]]; then
|
||||
log "Interface usb1 (ECM) créée"
|
||||
|
||||
# Configurer l'IP
|
||||
ip addr flush dev usb0 2>/dev/null || true
|
||||
ip addr add "${OTG_NETWORK_DEV}/30" dev usb0
|
||||
ip link set usb0 up
|
||||
# Configurer l'IP sur usb1 uniquement (évite le routage asymétrique)
|
||||
ip addr flush dev usb1 2>/dev/null || true
|
||||
ip addr add "${OTG_NETWORK_DEV}/30" dev usb1
|
||||
ip link set usb1 up
|
||||
|
||||
log "usb0 configuré: ${OTG_NETWORK_DEV}/30"
|
||||
log "usb1 configuré: ${OTG_NETWORK_DEV}/30"
|
||||
else
|
||||
err "Interface usb0 non créée après 5s"
|
||||
err "Interface usb1 non créée après 5s"
|
||||
return 1
|
||||
fi
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user