102 lines
5.0 KiB
Markdown
102 lines
5.0 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 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.
|