package device import ( "bufio" "fmt" "network-topology-discovery/pkg/models" "regexp" "strings" ) // H3CParser H3C设备解析器 type H3CParser struct { BaseParser } // GetCommands 获取H3C设备命令列表 func (p *H3CParser) GetCommands() []string { return []string{ "display version", "display interface", "display ip interface brief", "display lldp neighbor-list", } } // Parse 解析H3C设备输出 func (p *H3CParser) Parse(device *models.Device, outputs []string) error { if len(outputs) < 4 { return fmt.Errorf("insufficient command outputs") } p.parseVersion(device, outputs[0]) device.Interfaces = p.parseInterfaces(outputs[1], outputs[2]) device.Neighbors = p.parseNeighbors(outputs[3]) return nil } func (p *H3CParser) parseVersion(device *models.Device, output string) { hostnameRegex := regexp.MustCompile(`<(\S+)>`) if matches := hostnameRegex.FindStringSubmatch(output); len(matches) > 1 { device.Hostname = matches[1] } if strings.Contains(output, "Comware") { lines := strings.Split(output, "\n") for _, line := range lines { if strings.Contains(line, "Comware") { device.OSVersion = strings.TrimSpace(line) break } } } uptimeRegex := regexp.MustCompile(`uptime is\s+(\d+\s+\S+)`) if matches := uptimeRegex.FindStringSubmatch(output); len(matches) > 1 { device.Uptime = matches[1] } } func (p *H3CParser) parseInterfaces(interfaceOutput, briefOutput string) []models.Interface { var interfaces []models.Interface briefMap := p.parseInterfaceBrief(briefOutput) scanner := bufio.NewScanner(strings.NewReader(interfaceOutput)) var currentInterface *models.Interface for scanner.Scan() { line := scanner.Text() if nameRegex := regexp.MustCompile(`^(\S+)\s+current state:\s+(UP|DOWN)`); nameRegex.MatchString(line) { if currentInterface != nil { interfaces = append(interfaces, *currentInterface) } matches := nameRegex.FindStringSubmatch(line) currentInterface = &models.Interface{ Name: matches[1], Status: strings.ToLower(matches[2]), } if brief, ok := briefMap[currentInterface.Name]; ok { currentInterface.IP = brief.IP } } 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) { 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) { matches := ipRegex.FindStringSubmatch(line) currentInterface.IP = matches[1] currentInterface.Mask = matches[2] } if speedRegex := regexp.MustCompile(`(\d+)\s+(Kbps|Mbps|Gbps)`); speedRegex.MatchString(line) { matches := speedRegex.FindStringSubmatch(line) currentInterface.Speed = matches[1] + " " + matches[2] } } } if currentInterface != nil { interfaces = append(interfaces, *currentInterface) } return interfaces } func (p *H3CParser) parseInterfaceBrief(output string) map[string]models.Interface { interfaces := make(map[string]models.Interface) lines := strings.Split(output, "\n") for _, line := range lines { fields := strings.Fields(line) if len(fields) >= 4 { iface := models.Interface{ Name: fields[0], IP: fields[1], Status: strings.ToLower(fields[3]), } interfaces[iface.Name] = iface } } return interfaces } func (p *H3CParser) parseNeighbors(output string) []models.Neighbor { var neighbors []models.Neighbor scanner := bufio.NewScanner(strings.NewReader(output)) for scanner.Scan() { line := scanner.Text() if strings.Contains(line, "Local Interface") || strings.Contains(line, "-----") { continue } fields := strings.Fields(line) if len(fields) >= 5 { neighbor := models.Neighbor{ LocalInterface: fields[0], RemoteDevice: fields[2], RemoteInterface: fields[4], Protocol: "LLDP", } neighbors = append(neighbors, neighbor) } } return neighbors }