# 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 hoạt động 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ị. Để đảm bảo tỷ lệ phát hiện cao trên mọi hệ điều hành (Windows, macOS, Linux), scanner kết hợp 3 giai đoạn: 1. **Ping Sweep** — đánh thức thiết bị, điền ARP cache 2. **Đọc bảng ARP hệ điều hành** (`arp -a`) — không cần quyền Admin 3. **Scapy ARP broadcast** — bổ sung thiết bị chặn ICMP Bước 2 và 3 chạy **song song** để giảm tổng thời gian scan. --- ## 2. Luồng hoạt động chính (Hàm `scan_network`) **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. - Mỗi thiết bị phản hồi sẽ khiến hệ điều hành **tự ghi MAC vào ARP Cache**. - Sau khi sweep xong, chờ `0.3s` để OS kịp finalize ARP cache (giảm từ 1s trước đây). **Bước 2 + 3 — ARP Table & Scapy (song song)** - Hai hàm `_collect_arp()` và `_collect_scapy()` được submit vào `ThreadPoolExecutor(max_workers=2)` và chạy đồng thời: - `_collect_arp()`: đọc `arp -a`, parse regex lấy IP + MAC. - `_collect_scapy()`: gửi ARP broadcast, nhận phản hồi trực tiếp từ thiết bị. - Kết quả merge theo IP: ARP table làm nền, Scapy bổ sung IP còn thiếu. **Bước 4 — 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ẻ với 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 500` | 500ms (đơn vị ms) | 2s | | Linux | `ping -c 1 -W 1` | 1s (đơn vị giây) | 2s | > macOS và Linux dùng cùng flag `-W` nhưng đơn vị khác nhau — được xử lý tách biệt theo `sys.platform`. ### `_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`). - Gọi `progress_cb(done, total)` sau mỗi ping để UI cập nhật thanh tiến độ. ### `_collect_arp()` (nội bộ trong `scan_network`) Đọc và parse output `arp -a`, hỗ trợ đa nền tảng: - **Windows:** Regex nhận dạng dạng `cc-2d-21-a5-85-b0 dynamic`, chuẩn hóa MAC sang `cc:2d:21:a5:85:b0`. - **macOS/Linux:** Regex nhận dạng dạng `(192.168.1.1) at aa:bb:cc:dd:ee:ff`, bỏ qua entry `(incomplete)`. ### `_collect_scapy()` (nội bộ trong `scan_network`) - Gửi ARP `Who-has` broadcast (`Ether/ARP` qua `srp`) với **timeout 1s** (giảm từ 2s). - Stderr bị redirect tạm thời khi import scapy để tránh spam log ra console. - Tự động bỏ qua nếu scapy không khả dụng (không có Npcap / không có quyền root). --- ## 4. So sánh hiệu năng (trước và sau tối ưu) | Thay đổi | Trước | Sau | | --------------------------- | --------------------- | ------------------------------------ | | Ping workers | 100 (batching ~3 đợt) | `len(hosts)` (~254, tất cả cùng lúc) | | Ping timeout — Windows | 600ms | 300ms | | Ping timeout — macOS | 1ms (sai đơn vị) | 500ms | | Sleep sau ping sweep | 1.0s | 0.3s | | ARP + Scapy | Tuần tự | **Song song** | | Scapy timeout | 2s | 1s | | **Tổng thời gian scan /24** | ~5–7s | **~1.5–2s** | --- ## 5. Ưu & Nhược điểm **Ưu điểm:** - Tỷ lệ phát hiện thiết bị cao nhờ kết hợp 3 lớp. - Không cần quyền Admin/Root — ping sweep + ARP table vẫn tìm được ~90% thiết bị. - Tương thích đa nền tảng (Windows/macOS/Linux) qua xử lý riêng từng OS. - ARP table và Scapy chạy song song → không cộng dồn thời gian chờ. **Nhược điểm:** - Vẫn cần `sleep(0.3s)` để OS kịp ghi ARP cache sau ping sweep. - Thiết bị tắt hoàn toàn cả ICMP lẫn ARP sẽ không bị phát hiện. - Spawn ~254 process `ping` đồng thời trên Windows có overhead cao hơn Unix do Windows tạo process chậm hơn.