# 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** và **MAC Address** của từng thiết bị. Scanner hoạt động theo cơ chế 2 bước (Ping trước → ARP sau): 1. **ICMP Ping Sweep:** Chỉ những IP có phản hồi ping mới được ghi nhận là online. 2. **ARP Lookup:** Ngay sau khi IP phản hồi ping, OS tự động cập nhật ARP cache cho IP đó. Scanner lập tức query ARP table để lấy MAC chính xác nhất. > **Giải quyết vấn đề ARP cache cũ (stale entries):** Khác với phương pháp ARP scan truyền thống (`arp -a` liệt kê toàn mạng) thường dính thiết bị đã ngắt kết nối do bị cache, cách làm này **chỉ query ARP cho những IP vừa pass qua bài test ping**. Thiết bị offline sẽ rớt ở bước ping và không bao giờ được đưa vào danh sách. --- ## 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] │ ├── stage_cb("mac") ← Thông báo UI bắt đầu lấy MAC │ ├── _get_mac_from_arp(ip) × K ← Tra MAC song song cho K IP alive │ └── return [{"ip": ..., "mac": "AA:BB:CC:..."}, ...] ← 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 danh sách `alive_ips`. **Bước 2 — Địa chỉ MAC (ARP Lookup)** - Từ danh sách `alive_ips`, tạo ThreadPoolExecutor (max_workers=32) để gọi `_get_mac_from_arp(ip)` đồng thời. - Trích xuất MAC address bằng pattern matching chéo nền tảng. **Bước 3 — Trả về kết quả** - Danh sách sort tăng dần theo IP: `[{"ip": "192.168.1.2", "mac": "AA:BB:CC:DD:EE:FF"}, ...]` --- ## 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 độ. ### `_get_mac_from_arp(ip)` - Gọi lệnh hệ điều hành để đọc ARP cache cho IP cụ thể: - **Windows**: `arp -a ` - **macOS / Linux**: `arp -n ` - Sử dụng Regex để parse MAC address và trả về dưới format chuẩn `AA:BB:CC:DD:EE:FF`. - Nếu không tìm thấy, fallback thành `"N/A"`. ### `scan_network(network, progress_cb, stage_cb)` - Entry point chính. - `stage_cb("ping")` và `stage_cb("mac")` thông báo UI giai đoạn hiện tại. - Trả về `list[dict]` với format `{"ip": str, "mac": str}`, 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** | **~1–2s** | --- ## 5. Ưu & Nhược điểm **Ưu điểm:** - **Có đầy đủ IP và MAC**, rất hữu ích cho log và tracking lịch sử thiết bị nạp FW. - **Không bị dính ARP cache cũ**: Do chỉ lấy MAC của các IP vừa ping thành công. - Không cần quyền Admin/Root. - Không phụ thuộc thư viện bên ngoài (không cần Npcap / Scapy phức tạp). - Tương thích đa nền tảng (Windows/macOS/Linux). - Cực nhanh nhờ cơ chế full-parallel. **Nhược điểm:** - Thiết bị cố tình chặn gói tin ICMP (tắt ping) sẽ không bị phát hiện. - Ping 254 thiết bị cùng lúc bằng tiến trình con (`subprocess`) trên Windows có overhead hệ thống cao hơn Unix.