From 4abfd0716eed1377b791b396cdfe8965c0da9776 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 26 Apr 2026 00:49:06 +0800 Subject: [PATCH] =?UTF-8?q?Fix:=20=E4=BF=AE=E6=AD=A3H3C=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=E9=80=82=E9=85=8D=E7=9C=9F=E5=AE=9E?= =?UTF-8?q?=E8=BE=93=E5=87=BA=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 支持接口名和状态分两行的格式 - 修正MAC地址正则: hardware address: (不是Hardware address is) - 修正IP地址正则: Internet address: x.x.x.x/24 (CIDR格式) - 添加CIDR到子网掩码转换函数 - 支持多种接口类型前缀匹配 --- internal/device/h3c.go | 58 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/internal/device/h3c.go b/internal/device/h3c.go index 26eb1ff..1bba855 100644 --- a/internal/device/h3c.go +++ b/internal/device/h3c.go @@ -91,10 +91,13 @@ func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []model scanner := bufio.NewScanner(strings.NewReader(interfaceOutput)) var currentInterface *models.Interface + var pendingInterfaceName string // 暂存接口名 for scanner.Scan() { line := scanner.Text() + // H3C接口输出格式1: 接口名和状态在同一行 + // GigabitEthernet1/0/0 current state: UP if nameRegex := regexp.MustCompile(`^(\S+)\s+current state:\s+(UP|DOWN)`); nameRegex.MatchString(line) { if currentInterface != nil { interfaces = append(interfaces, *currentInterface) @@ -108,21 +111,53 @@ func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []model if brief, ok := briefMap[currentInterface.Name]; ok { currentInterface.IP = brief.IP } + pendingInterfaceName = "" + continue } + // H3C接口输出格式2: 接口名单独一行,下一行是状态 + // GigabitEthernet1/0/0 + // Current state: DOWN + if pendingInterfaceName != "" && regexp.MustCompile(`^Current state:\s+(UP|DOWN)`).MatchString(line) { + matches := regexp.MustCompile(`^Current state:\s+(UP|DOWN)`).FindStringSubmatch(line) + if currentInterface != nil { + interfaces = append(interfaces, *currentInterface) + } + currentInterface = &models.Interface{ + Name: pendingInterfaceName, + Status: strings.ToLower(matches[1]), + } + + if brief, ok := briefMap[currentInterface.Name]; ok { + currentInterface.IP = brief.IP + } + pendingInterfaceName = "" + continue + } + + // 匹配接口名(单独一行的情况) + // 格式: GigabitEthernet1/0/0 + if interfaceNameRegex := regexp.MustCompile(`^(GigabitEthernet|Ten-GigabitEthernet|FortyGigE|HundredGigE|Ethernet|Serial|LoopBack|Vlanif|NULL|Bridge-Aggregate|Route-Aggregate)\S*`); interfaceNameRegex.MatchString(line) { + pendingInterfaceName = interfaceNameRegex.FindString(line) + continue + } + + // 解析接口属性 if currentInterface != nil { if descRegex := regexp.MustCompile(`Description:\s+(.+)`); descRegex.MatchString(line) { currentInterface.Description = descRegex.FindStringSubmatch(line)[1] } - if macRegex := regexp.MustCompile(`Hardware address is\s+(\S+)`); macRegex.MatchString(line) { + if macRegex := regexp.MustCompile(`hardware address:\s+(\S+)`); macRegex.MatchString(line) { currentInterface.MAC = macRegex.FindStringSubmatch(line)[1] } - if ipRegex := regexp.MustCompile(`IP Address:\s+(\d+\.\d+\.\d+\.\d+)\s+Subnet Mask:\s+(\d+\.\d+\.\d+\.\d+)`); ipRegex.MatchString(line) { + // 匹配IP地址格式: Internet address: 192.168.0.1/24 (primary) + if ipRegex := regexp.MustCompile(`Internet address:\s+(\d+\.\d+\.\d+\.\d+)/(\d+)`); ipRegex.MatchString(line) { matches := ipRegex.FindStringSubmatch(line) currentInterface.IP = matches[1] - currentInterface.Mask = matches[2] + // CIDR转换为子网掩码 + currentInterface.Mask = cidrToMask(matches[2]) } if speedRegex := regexp.MustCompile(`(\d+)\s+(Kbps|Mbps|Gbps)`); speedRegex.MatchString(line) { @@ -139,6 +174,23 @@ func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []model return interfaces } +// cidrToMask CIDR转换为子网掩码 +func cidrToMask(cidr string) string { + var mask int + fmt.Sscanf(cidr, "%d", &mask) + + s := uint32(0) + for i := 0; i < mask; i++ { + s |= (1 << (31 - uint(i))) + } + + return fmt.Sprintf("%d.%d.%d.%d", + (s>>24)&0xFF, + (s>>16)&0xFF, + (s>>8)&0xFF, + s&0xFF) +} + // parseARPTable 解析ARP表,建立MAC到IP的映射 func (p *H3CParser) parseARPTable(output string) map[string]string { macToIP := make(map[string]string)