Files
membank/auto-check/pkg/discovery/arp.go
张威33321 906bb54aaa 重构 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(串行扫描无需并发数)
2026-08-12 17:11:59 +08:00

78 lines
1.7 KiB
Go

package discovery
import (
"os"
"os/exec"
"runtime"
"strings"
)
// lookupMAC 从 ARP 表获取 IP 对应的 MAC 地址(跨平台)
// 返回空字符串表示无法获取
func lookupMAC(ip string) string {
switch runtime.GOOS {
case "linux":
return macFromProcNetArp(ip)
case "windows":
return macFromWindowsArp(ip)
default:
return macFromUnixArp(ip)
}
}
// macFromProcNetArp 解析 Linux /proc/net/arp
func macFromProcNetArp(ip string) string {
data, err := os.ReadFile("/proc/net/arp")
if err != nil {
return ""
}
for _, line := range strings.Split(string(data), "\n")[1:] {
fields := strings.Fields(line)
if len(fields) >= 4 && fields[0] == ip {
mac := fields[3]
if mac != "" && mac != "00:00:00:00:00:00" {
return mac
}
}
}
return ""
}
// macFromWindowsArp 解析 Windows `arp -a` 输出
func macFromWindowsArp(ip string) string {
out, err := exec.Command("arp", "-a").Output()
if err != nil {
return ""
}
for _, line := range strings.Split(string(out), "\n") {
fields := strings.Fields(line)
if len(fields) >= 2 && fields[0] == ip {
mac := strings.ReplaceAll(fields[1], "-", ":")
if mac != "" && mac != "00:00:00:00:00:00" {
return strings.ToLower(mac)
}
}
}
return ""
}
// macFromUnixArp 解析 macOS/Linux `arp -n` 输出
func macFromUnixArp(ip string) string {
out, err := exec.Command("arp", "-n", ip).Output()
if err != nil {
return ""
}
for _, line := range strings.Split(string(out), "\n") {
fields := strings.Fields(line)
for i, f := range fields {
if f == "("+ip+")" && i+2 < len(fields) {
mac := fields[i+2]
if mac != "" && mac != "ff:ff:ff:ff:ff:ff" {
return strings.ToLower(mac)
}
}
}
}
return ""
}