Initial commit: 网络拓扑发现系统
- 支持Cisco、华为、H3C、ASA、Linux、Windows设备 - SSH远程采集设备信息 - 自动发现网络拓扑(LLDP/CDP) - Web可视化界面 - 支持旧版SSH加密算法兼容
This commit is contained in:
@@ -0,0 +1,107 @@
|
||||
package device
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"network-topology-discovery/pkg/models"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// LinuxParser Linux服务器解析器
|
||||
type LinuxParser struct {
|
||||
BaseParser
|
||||
}
|
||||
|
||||
// GetCommands 获取Linux命令列表
|
||||
func (p *LinuxParser) GetCommands() []string {
|
||||
return []string{
|
||||
"hostname",
|
||||
"uname -a",
|
||||
"ip addr show",
|
||||
"ip link show",
|
||||
"uptime",
|
||||
}
|
||||
}
|
||||
|
||||
// Parse 解析Linux输出
|
||||
func (p *LinuxParser) Parse(device *models.Device, outputs []string) error {
|
||||
if len(outputs) < 5 {
|
||||
return fmt.Errorf("insufficient command outputs")
|
||||
}
|
||||
|
||||
device.Hostname = strings.TrimSpace(outputs[0])
|
||||
device.OSVersion = p.parseOSVersion(outputs[1])
|
||||
device.Uptime = strings.TrimSpace(outputs[4])
|
||||
device.Interfaces = p.parseInterfaces(outputs[2], outputs[3])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *LinuxParser) parseOSVersion(output string) string {
|
||||
// 从uname提取内核版本
|
||||
parts := strings.Fields(output)
|
||||
if len(parts) >= 3 {
|
||||
return fmt.Sprintf("Linux %s", parts[2])
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func (p *LinuxParser) parseInterfaces(addrOutput, linkOutput string) []models.Interface {
|
||||
var interfaces []models.Interface
|
||||
|
||||
// 解析ip addr show输出
|
||||
interfaceMap := make(map[string]*models.Interface)
|
||||
var currentInterface *models.Interface
|
||||
|
||||
lines := strings.Split(addrOutput, "\n")
|
||||
for _, line := range lines {
|
||||
// 匹配接口: 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500
|
||||
if nameRegex := regexp.MustCompile(`^\d+:\s+(\S+):\s+<([^>]*)>`); nameRegex.MatchString(line) {
|
||||
matches := nameRegex.FindStringSubmatch(line)
|
||||
name := strings.TrimSuffix(matches[1], ":")
|
||||
flags := matches[2]
|
||||
|
||||
currentInterface = &models.Interface{
|
||||
Name: name,
|
||||
Status: "down",
|
||||
}
|
||||
|
||||
if strings.Contains(flags, "UP") {
|
||||
currentInterface.Status = "up"
|
||||
}
|
||||
|
||||
// 提取MTU
|
||||
if mtuRegex := regexp.MustCompile(`mtu\s+(\d+)`); mtuRegex.MatchString(line) {
|
||||
matches := mtuRegex.FindStringSubmatch(line)
|
||||
currentInterface.MTU = 0
|
||||
fmt.Sscanf(matches[1], "%d", ¤tInterface.MTU)
|
||||
}
|
||||
|
||||
interfaceMap[name] = currentInterface
|
||||
interfaces = append(interfaces, *currentInterface)
|
||||
}
|
||||
|
||||
if currentInterface != nil {
|
||||
// 提取MAC地址
|
||||
if macRegex := regexp.MustCompile(`link/ether\s+(\S+)`); macRegex.MatchString(line) {
|
||||
matches := macRegex.FindStringSubmatch(line)
|
||||
currentInterface.MAC = matches[1]
|
||||
}
|
||||
|
||||
// 提取IP地址
|
||||
if ipRegex := regexp.MustCompile(`inet\s+(\d+\.\d+\.\d+\.\d+)/(\d+)`); ipRegex.MatchString(line) {
|
||||
matches := ipRegex.FindStringSubmatch(line)
|
||||
currentInterface.IP = matches[1]
|
||||
currentInterface.Mask = matches[2]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新接口列表
|
||||
finalInterfaces := make([]models.Interface, 0, len(interfaceMap))
|
||||
for _, iface := range interfaceMap {
|
||||
finalInterfaces = append(finalInterfaces, *iface)
|
||||
}
|
||||
|
||||
return finalInterfaces
|
||||
}
|
||||
Verwijs in nieuw issue
Block a user