103 lines
4.5 KiB
Markdown
103 lines
4.5 KiB
Markdown
# 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** | **~1–2s** |
|
||
|
||
---
|
||
|
||
## 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 (~1–2s 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.
|