Fix: 修正H3C接口解析器适配真实输出格式
- 支持接口名和状态分两行的格式 - 修正MAC地址正则: hardware address: (不是Hardware address is) - 修正IP地址正则: Internet address: x.x.x.x/24 (CIDR格式) - 添加CIDR到子网掩码转换函数 - 支持多种接口类型前缀匹配
This commit is contained in:
+55
-3
@@ -91,10 +91,13 @@ func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []model
|
|||||||
|
|
||||||
scanner := bufio.NewScanner(strings.NewReader(interfaceOutput))
|
scanner := bufio.NewScanner(strings.NewReader(interfaceOutput))
|
||||||
var currentInterface *models.Interface
|
var currentInterface *models.Interface
|
||||||
|
var pendingInterfaceName string // 暂存接口名
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
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 nameRegex := regexp.MustCompile(`^(\S+)\s+current state:\s+(UP|DOWN)`); nameRegex.MatchString(line) {
|
||||||
if currentInterface != nil {
|
if currentInterface != nil {
|
||||||
interfaces = append(interfaces, *currentInterface)
|
interfaces = append(interfaces, *currentInterface)
|
||||||
@@ -108,21 +111,53 @@ func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []model
|
|||||||
if brief, ok := briefMap[currentInterface.Name]; ok {
|
if brief, ok := briefMap[currentInterface.Name]; ok {
|
||||||
currentInterface.IP = brief.IP
|
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 currentInterface != nil {
|
||||||
if descRegex := regexp.MustCompile(`Description:\s+(.+)`); descRegex.MatchString(line) {
|
if descRegex := regexp.MustCompile(`Description:\s+(.+)`); descRegex.MatchString(line) {
|
||||||
currentInterface.Description = descRegex.FindStringSubmatch(line)[1]
|
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]
|
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)
|
matches := ipRegex.FindStringSubmatch(line)
|
||||||
currentInterface.IP = matches[1]
|
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) {
|
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
|
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的映射
|
// parseARPTable 解析ARP表,建立MAC到IP的映射
|
||||||
func (p *H3CParser) parseARPTable(output string) map[string]string {
|
func (p *H3CParser) parseARPTable(output string) map[string]string {
|
||||||
macToIP := make(map[string]string)
|
macToIP := make(map[string]string)
|
||||||
|
|||||||
Reference in New Issue
Block a user