Fix: 修正H3C接口解析器适配真实输出格式

- 支持接口名和状态分两行的格式
- 修正MAC地址正则: hardware address: (不是Hardware address is)
- 修正IP地址正则: Internet address: x.x.x.x/24 (CIDR格式)
- 添加CIDR到子网掩码转换函数
- 支持多种接口类型前缀匹配
This commit is contained in:
Your Name
2026-04-26 00:49:06 +08:00
orang tua 8b7dbf2886
melakukan 4abfd0716e
+55 -3
Melihat File
@@ -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)