fix: switch tcp_check mode to TCP-only instead of ICMP+TCP

Previously tcp_check required both ICMP and TCP to pass. This caused
two failure modes: hosts with ICMP rate-limiting under scan load were
missed (ICMP fails → TCP never tried), and the AND logic was confusing.

In TCP-only mode, proxy-ARP gateways are still filtered out because
they never spoof TCP replies. Hosts with rate-limited ICMP (e.g. some
WiFi APs during a full /24 sweep) are now correctly detected via TCP.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-18 15:12:04 +02:00
parent 4b0aa1edf2
commit 93ab343db7
2 changed files with 15 additions and 10 deletions
+9 -4
View File
@@ -115,10 +115,15 @@ def _tcp_check(ip: str) -> bool:
def _scan_one(ip: str, dns_server: str, vlan_id: int, cidr: str, tcp_check: bool = False) -> Optional[DiscoveredHost]: def _scan_one(ip: str, dns_server: str, vlan_id: int, cidr: str, tcp_check: bool = False) -> Optional[DiscoveredHost]:
if not _ping(ip): if tcp_check:
return None # TCP-only mode: bypasses ICMP entirely.
if tcp_check and not _tcp_check(ip): # Proxy-ARP gateways never spoof TCP replies, so ghost IPs are filtered
return None # without ICMP. Also catches hosts whose ICMP is rate-limited under load.
if not _tcp_check(ip):
return None
else:
if not _ping(ip):
return None
hostname = _ptr_lookup(ip, dns_server) if dns_server else None hostname = _ptr_lookup(ip, dns_server) if dns_server else None
return DiscoveredHost(ip=ip, hostname=hostname, vlan_id=vlan_id, cidr=cidr) return DiscoveredHost(ip=ip, hostname=hostname, vlan_id=vlan_id, cidr=cidr)
+6 -6
View File
@@ -128,8 +128,8 @@ const LANGS = {
scanAddresses: 'adresses sur', scanAddresses: 'adresses sur',
scanVlans: 'VLAN(s)', scanVlans: 'VLAN(s)',
scanNote: 'Chaque hôte est pingé puis interrogé en DNS.', scanNote: 'Chaque hôte est pingé puis interrogé en DNS.',
tcpCheckLabel: 'Vérification TCP (anti proxy-ARP)', tcpCheckLabel: 'Scan TCP (anti proxy-ARP)',
tcpCheckHint: 'Sonde chaque hôte sur les ports 22, 80, 443, 8080, 8443. Élimine les faux positifs UniFi/proxy-ARP. Peut rater uniquement les équipements dont le pare-feu bloque silencieusement (DROP) tous ces ports — un hôte renvoyant RST sur un port fermé est correctement détecté.', tcpCheckHint: 'Utilise TCP au lieu de ICMP pour détecter les hôtes actifs (ports 22, 80, 443, 8080, 8443). Élimine les faux positifs proxy-ARP (UniFi…) et détecte les équipements dont le ping ICMP est bridé sous charge. Peut rater les équipements qui bloquent silencieusement (DROP) tous ces ports.',
hostsFound: 'hôte(s) découvert(s)', hostsFound: 'hôte(s) découvert(s)',
addressesScanned: 'adresses scannées', addressesScanned: 'adresses scannées',
newHosts: 'nouveaux', newHosts: 'nouveaux',
@@ -287,8 +287,8 @@ const LANGS = {
scanAddresses: 'addresses on', scanAddresses: 'addresses on',
scanVlans: 'VLAN(s)', scanVlans: 'VLAN(s)',
scanNote: 'Each host is pinged then queried via DNS.', scanNote: 'Each host is pinged then queried via DNS.',
tcpCheckLabel: 'TCP check (anti proxy-ARP)', tcpCheckLabel: 'TCP scan (anti proxy-ARP)',
tcpCheckHint: 'Probes each host on ports 22, 80, 443, 8080, 8443. Eliminates UniFi/proxy-ARP false positives. Only misses devices whose firewall silently drops (DROP) all probed ports — a host sending RST on a closed port is correctly detected.', tcpCheckHint: 'Uses TCP instead of ICMP to detect live hosts (ports 22, 80, 443, 8080, 8443). Eliminates proxy-ARP false positives (UniFi…) and detects hosts whose ICMP is rate-limited under load. May miss devices that silently block (DROP) all probed ports.',
hostsFound: 'host(s) found', hostsFound: 'host(s) found',
addressesScanned: 'addresses scanned', addressesScanned: 'addresses scanned',
newHosts: 'new', newHosts: 'new',
@@ -445,8 +445,8 @@ const LANGS = {
scanAddresses: 'direcciones en', scanAddresses: 'direcciones en',
scanVlans: 'VLAN(s)', scanVlans: 'VLAN(s)',
scanNote: 'Cada host es pingado y luego consultado en DNS.', scanNote: 'Cada host es pingado y luego consultado en DNS.',
tcpCheckLabel: 'Verificación TCP (anti proxy-ARP)', tcpCheckLabel: 'Escaneo TCP (anti proxy-ARP)',
tcpCheckHint: 'Sondea cada host en los puertos 22, 80, 443, 8080, 8443. Elimina falsos positivos UniFi/proxy-ARP. Solo puede omitir equipos cuyo firewall descarta silenciosamente (DROP) todos los puertos sondeados — un host que responde RST en un puerto cerrado se detecta correctamente.', tcpCheckHint: 'Usa TCP en lugar de ICMP para detectar hosts activos (puertos 22, 80, 443, 8080, 8443). Elimina falsos positivos de proxy-ARP (UniFi…) y detecta hosts con ICMP limitado bajo carga. Puede omitir equipos que bloqueen silenciosamente (DROP) todos los puertos sondeados.',
hostsFound: 'host(s) descubierto(s)', hostsFound: 'host(s) descubierto(s)',
addressesScanned: 'direcciones escaneadas', addressesScanned: 'direcciones escaneadas',
newHosts: 'nuevos', newHosts: 'nuevos',