From 69b620f8328c69ea22130bcfcd2e5d00824ca47e Mon Sep 17 00:00:00 2001 From: MinhNN Date: Mon, 9 Mar 2026 14:11:44 +0700 Subject: [PATCH] update doc --- README.md | 6 +-- docs/scanner_docs.md | 112 +++++++++++++++++++++++++++++-------------- 2 files changed, 80 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 5cfd19a..9feb1e6 100644 --- a/README.md +++ b/README.md @@ -126,9 +126,9 @@ Output: `dist\Mira_Firmware_Loader.exe` — không cần cài Python trên máy | Giai đoạn | Mô tả | | -------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| **Ping Sweep** | Gửi ping song song (100 threads) đến toàn bộ host trong dải `/24` để đánh thức thiết bị và điền ARP cache | -| **ARP Table** | Đọc `arp -a` bằng regex, hỗ trợ cả định dạng Windows (`cc-2d-...`) và macOS/Linux (`aa:bb:...`) | -| **Scapy ARP** | Gửi ARP broadcast trực tiếp để lấp khoảng trống. Yêu cầu Npcap (Windows) hoặc root (Linux); tự động bỏ qua nếu không khả dụng | +| **Ping Sweep** | Gửi ping đồng thời tới toàn bộ host trong dải `/24` (tất cả cùng lúc, không batching) để đánh thức thiết bị và điền ARP cache | +| **ARP Table** | Đọc `arp -a` bằng regex, hỗ trợ cả định dạng Windows (`cc-2d-...`) và macOS/Linux (`aa:bb:...`) | +| **Scapy ARP** | Chạy **song song** với ARP Table — gửi ARP broadcast để lấp khoảng trống. Yêu cầu Npcap (Windows) hoặc root (Linux); tự động bỏ qua nếu không khả dụng | Kết quả được merge theo IP và sort tăng dần trước khi trả về UI. diff --git a/docs/scanner_docs.md b/docs/scanner_docs.md index 93890b5..0169836 100644 --- a/docs/scanner_docs.md +++ b/docs/scanner_docs.md @@ -1,59 +1,101 @@ # 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 (IP Scanner) trong file `scanner.py` được thiết kế để dò tìm và liệt kê tất cả các thiết bị đang hoạt động trên một dải mạng (ví dụ: `192.168.1.0/24`). Nó theo dõi và trả về danh sách các đối tượng chứa địa chỉ **IP** và **MAC Address** của từng thiết bị. -Để đảm bảo tỷ lệ phát hiện cao nhất trên các hệ điều hành khác nhau (Windows, macOS, Linux), script sử dụng kết hợp hai phương pháp dò tìm: -1. **Quét mồi bằng Ping (Ping Sweep) kết hợp đọc bảng ARP tĩnh của hệ điều hành.** -2. **Quét ARP trực tiếp ở Tầng 2 (Layer 2) bằng thư viện `scapy`.** +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`) -Đây là hàm được gọi trực tiếp khi muốn quét một mạng. Trình tự rà quét diễn ra qua các bước sau: +**Bước 1 — Ping Sweep** -**Bước 1: "Đánh thức" các thiết bị (Ping Sweep)** -- Hệ thống gọi hàm `_ping_sweep(network)` để gửi gói Ping (ICMP Echo Request) đồng loạt tới tất cả các IP có thể có trong mạng. -- Mục đích của bước này là buộc các thiết bị phản hồi, từ đó hệ điều hành của máy đang chạy lệnh sẽ **tự động ghi nhận địa chỉ MAC** của các thiết bị đó vào bộ nhớ đệm ARP (ARP Cache). -- Hệ thống tạm dừng 1 giây để đảm bảo hệ điều hành kịp lưu thông tin vào ARP Cache. +- 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: Lấy dữ liệu từ bảng ARP của Hệ điều hành (Method 1)** -- Thực thi lệnh hệ thống `arp -a` để đọc ARP Cache. -- Kết quả được phân tích cú pháp (Regex) để trích xuất IP và MAC tương ứng, tương thích linh hoạt với cả đầu ra của Windows lẫn macOS/Linux. -- Các thiết bị đọc được lưu vào danh sách nháp (biến `seen`). +**Bước 2 + 3 — ARP Table & Scapy (song song)** -**Bước 3: Quét sâu với Scapy (Method 2 - Dự phòng/Bổ sung)** -- Script gọi thêm thư viện `scapy` để phát một thông điệp "ARP Who-has" tới địa chỉ MAC Broadcast (`ff:ff:ff:ff:ff:ff`). -- Phương pháp này giúp phát hiện ra các thiết bị chặn Ping (chặn ICMP) ở Bước 1 nhưng buộc phải phản hồi gói ARP ở tầng Data Link. -- Những thiết bị mới tìm thấy (nếu chưa có trong danh sách `seen` ở Bước 2) sẽ được bổ sung vào danh sách. +- 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 các thiết bị cuối cùng được sắp xếp từ nhỏ đến lớn dựa trên địa chỉ IP và trả về dưới dạng: +**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 hỗ trợ +## 3. Phân tích chi tiết các hàm -### `_ping_sweep(network)` \& `_ping_one(ip, is_win)` -- **Nhiệm vụ:** Quét Ping hàng loạt (Ping Sweep). -- **Cách thức hoạt động:** Sử dụng `ThreadPoolExecutor` để chạy **tối đa 100 luồng (threads) song song**. Điều này giúp việc gửi Ping hàng loạt diễn ra cực kì nhanh chóng tính bằng giây thay vì phải đợi ping từng IP một. -- **Biện pháp an toàn:** Script có cơ chế tự bảo vệ chặn flood mạng: nó sẽ **từ chối chạy Ping Sweep** nếu dải mạng (subnet) lớn hơn 256 địa chỉ IP (tức là chỉ chạy cho dải mạng từ `/24` trở xuống). +### `_ping_one(ip, is_win)` -### `_scan_with_arp_table(network)` -- **Nhiệm vụ:** Hàm chạy độc lập để quét tìm thiết bị mà **không cần thông qua đặc quyền Root/Administrator** (fallback method). -- **Hỗ trợ Đa nền tảng:** - - **Trên Windows (`win32`):** Chuẩn hóa định dạng chuẩn MAC từ gạch ngang sang dấu hai chấm (vd: từ `cc-2d-21...` sang `cc:2d:21...`). Nó dựa vào Regex nhận diện các dòng chuẩn xuất ra có chữ `dynamic` hoặc `static`. - - **Trên macOS / Linux:** Dùng Regex đọc định dạng chuẩn riêng biệt ví dụ: `? (192.168.1.1) at aa:bb:cc:dd:ee:ff on en0`. Loại bỏ những địa chỉ lỗi bị đánh dấu là `(incomplete)`. +Ping một IP đơn lẻ với timeout tối ưu theo nền tảng: -### `_scan_with_scapy(network)` -- **Nhiệm vụ:** Công cụ quét cực mạnh ở Tầng 2 (Layer 2) của mô hình mạng OSI. -- **Đặc thù:** Đòi hỏi người dùng phải cấp quyền Sudo/Root trên Linux/macOS hoặc phải cài đặt thư viện phần mềm **Npcap/WinPcap** trên Windows thì mới có thể sử dụng. Gửi gói `srp` bằng `scapy` với timeout là 3 giây để lấy về thông tin phần cứng đích thực. +| 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. Tóm tắt Ưu & Nhược điểm của thiết kế này +## 4. So sánh hiệu năng (trước và sau tối ưu) -- **Ưu điểm:** Khả năng dò tìm diện rộng rất cao vì sự kết hợp song song của hai phương pháp. Nếu thiết bị không có quyền Root/Sudo để chạy `scapy`, nó vẫn có thể tìm được ít nhất ~90% thiết bị trong mạng nhờ tính năng Ping Sweeping mạnh mẽ. Tính tương thích chéo OS (Windows/Mac/Linux) được xử lý rất tốt và gọn gàng qua Regex. -- **Nhược điểm:** Tốn thêm 1 giây (hàm `time.sleep(1)`) và thêm vài giây timeout tổng cộng, do cần chờ để làm đầy bộ nhớ đệm ARP trước khi quét sâu. Nếu thiết bị đích cố tình tắt phản hồi ARP, thì vẫn có khả năng bị lọt dán mạng. +| 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.