重构 auto-check:状态数据下沉各包,workflow 精简为纯调度

- discovery: ping 探测存活 + ARP 解析 MAC,包级 Devices map,串行扫描
- stress: 脚本生成模式(BuildScript/ParseResults),ToolSet 工具检测,包级 Results map
- report: 包级 Printed map,SaveAndPrintDeviceReport 保存+打印
- sshclient: 包级 RunCommand
- workflow: 仅持有 config,Start() 固定循环,直接调用各包方法
- config: 移除 ScanConfig.Concurrency(串行扫描无需并发数)
This commit is contained in:
张威33321
2026-08-12 17:11:59 +08:00
parent 700ba91883
commit 906bb54aaa
15 changed files with 708 additions and 871 deletions

View File

@@ -0,0 +1,106 @@
package discovery
import (
"fmt"
"net"
"os/exec"
"runtime"
"time"
"auto-check/pkg/model"
)
// Scanner 网段扫描器(串行,按顺序逐个探测)
type Scanner struct {
CIDR string
Timeout time.Duration
}
// NewScanner 创建扫描器
func NewScanner(cidr string, timeout time.Duration) *Scanner {
return &Scanner{
CIDR: cidr,
Timeout: timeout,
}
}
// Scan 扫描网段,返回存活设备列表(含 MAC 地址)
// 串行逐个探测,每个 IP 有超时保护
func (s *Scanner) Scan() []model.Device {
ips, ok := s.candidateIPs()
if !ok {
return nil
}
fmt.Printf("[扫描] 网段 %s共 %d 个IP开始探测...\n", s.CIDR, len(ips))
var results []model.Device
for _, ip := range ips {
if dev, ok := s.probe(ip); ok {
results = append(results, dev)
}
}
fmt.Printf("[扫描] 完成,发现 %d 台存活设备\n", len(results))
return results
}
// candidateIPs 解析网段并生成候选 IP 列表(排除网络地址和广播地址)
func (s *Scanner) candidateIPs() ([]net.IP, bool) {
ip, ipnet, err := net.ParseCIDR(s.CIDR)
if err != nil {
fmt.Printf("[扫描] 网段解析失败: %v\n", err)
return nil, false
}
var ips []net.IP
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
dst := make(net.IP, len(ip))
copy(dst, ip)
ips = append(ips, dst)
}
if len(ips) > 2 {
ips = ips[1 : len(ips)-1]
}
return ips, true
}
// probe 探测单个 IP存活则返回设备信息MAC 通过 ARP 表查询)
func (s *Scanner) probe(ip net.IP) (model.Device, bool) {
if !s.isAlive(ip) {
return model.Device{}, false
}
mac := lookupMAC(ip.String())
desc := "无MAC"
if mac != "" {
desc = mac
}
fmt.Printf(" [+] %s 存活 (MAC: %s)\n", ip, desc)
return model.Device{IP: ip.String(), MAC: mac}, true
}
// isAlive 用 ping 探测单个 IP 是否存活(内置超时保护)
func (s *Scanner) isAlive(ip net.IP) bool {
waitMs := s.Timeout.Milliseconds()
if waitMs < 1000 {
waitMs = 1000
}
var args []string
switch runtime.GOOS {
case "windows":
args = []string{"-n", "1", "-w", fmt.Sprintf("%d", waitMs), ip.String()}
case "darwin":
args = []string{"-c", "1", "-W", fmt.Sprintf("%d", waitMs), ip.String()}
default:
args = []string{"-c", "1", "-W", fmt.Sprintf("%d", waitMs/1000), ip.String()}
}
return exec.Command("ping", args...).Run() == nil
}
// inc IP 递增
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}