Files
Mira_Firmware_Loader/docs/scanner_docs.md
2026-03-10 17:54:56 +07:00

4.5 KiB
Raw Blame History

Tài liệu Kỹ thuật: Cơ chế Quét IP trên Mạng (Network Scanner)

1. Tổng quan

Thành phần quét IP trong scanner.py dò tìm và liệt kê tất cả thiết bị đang thực sự online trên một dải mạng (ví dụ: 192.168.1.0/24), trả về danh sách chứa IP của từng thiết bị.

Scanner chỉ sử dụng ICMP Ping — thiết bị phải phản hồi ping thì mới được liệt kê. Cơ chế này đảm bảo kết quả chính xác, tránh hiện tượng hiển thị thiết bị đã ngắt kết nối do ARP cache cũ trên router/OS.

Lý do loại bỏ ARP và Scapy: Bảng ARP của hệ điều hành và router giữ cache entry trong nhiều phút, khiến thiết bị đã rút vẫn xuất hiện trong kết quả scan. Ping trực tiếp là phương pháp duy nhất xác nhận thiết bị thực sự đang hoạt động tại thời điểm scan.


2. Luồng hoạt động chính (Hàm scan_network)

scan_network(network)
    │
    ├── stage_cb("ping")          ← Thông báo UI bắt đầu quét
    │
    ├── _ping_sweep(network)      ← Ping đồng thời toàn bộ host
    │       │
    │       ├── _ping_one(ip) × N ← Mỗi host 1 thread
    │       │
    │       └── return [alive IPs]
    │
    └── return [{"ip": ..., "mac": "N/A"}, ...]   ← Sorted by IP

Bước 1 — Ping Sweep

  • Gọi _ping_sweep(network): gửi ICMP Echo Request đồng thời tới toàn bộ host trong dải mạng.
  • Chỉ các IP có returncode == 0 (phản hồi thành công) mới được đưa vào kết quả.

Bước 2 — Trả về kết quả

  • Danh sách sort tăng dần theo IP: [{"ip": "192.168.1.2", "mac": "N/A"}, ...]
  • Trường mac luôn là "N/A" — giữ nguyên cấu trúc dict để tương thích với UI và các module khác.

3. Phân tích chi tiết các hàm

_ping_one(ip, is_win)

Ping một IP đơn lẻ, trả về True nếu host phản hồi, False nếu không.

Timeout tối ưu theo nền tảng:

OS Lệnh Timeout wait Timeout process
Windows ping -n 1 -w 300 300ms 2s
macOS ping -c 1 -W 300 300ms 2s
Linux ping -c 1 -W 1 1s 2s

macOS và Linux dùng cùng flag -W nhưng đơn vị khác nhau (macOS: ms, Linux: giây) — được xử lý tách biệt theo sys.platform.

Windows sử dụng CREATE_NO_WINDOW flag để tránh mở cửa sổ console cho mỗi subprocess.

_ping_sweep(network, progress_cb)

  • Tạo ThreadPoolExecutor(max_workers=len(hosts))toàn bộ host ping đồng thời, không batching.
  • Giới hạn an toàn: chỉ chạy với subnet /24 trở xuống (num_addresses <= 256).
  • Trả về danh sách IP (string) đã phản hồi thành công.
  • Gọi progress_cb(done, total) sau mỗi ping để UI cập nhật thanh tiến độ.

scan_network(network, progress_cb, stage_cb)

  • Entry point chính.
  • stage_cb("ping") thông báo UI giai đoạn hiện tại.
  • Trả về list[dict] với format {"ip": str, "mac": "N/A"}, sorted theo IP tăng dần.

4. Hiệu năng

Thông số Giá trị
Ping workers len(hosts) (~254, tất cả cùng lúc)
Ping timeout — Windows 300ms
Ping timeout — macOS 300ms
Ping timeout — Linux 1s
Process timeout 2s
Tổng thời gian scan /24 ~12s

5. Ưu & Nhược điểm

Ưu điểm:

  • Kết quả chính xác — chỉ thiết bị thực sự online mới xuất hiện, không bị ảnh hưởng bởi ARP cache cũ.
  • Không cần quyền Admin/Root.
  • Không phụ thuộc thư viện bên ngoài (không cần Scapy, Npcap).
  • Tương thích đa nền tảng (Windows/macOS/Linux).
  • Nhanh (~12s cho /24) nhờ ping toàn bộ host đồng thời.

Nhược điểm:

  • Không có thông tin MAC address.
  • Thiết bị chặn ICMP (tắt ping) sẽ không bị phát hiện.
  • Spawn ~254 process ping đồng thời trên Windows có overhead cao hơn Unix.