| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package device
- import (
- "fmt"
- "network-topology-discovery/pkg/models"
- "strings"
- )
- // WindowsParser Windows Server解析器
- type WindowsParser struct {
- BaseParser
- }
- // GetCommands 获取Windows命令列表
- func (p *WindowsParser) GetCommands() []string {
- return []string{
- "hostname",
- "systeminfo | findstr /B /C:\"OS Name\" /C:\"OS Version\"",
- "Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, MacAddress, LinkSpeed | Format-List",
- "Get-NetIPAddress | Where-Object AddressFamily -eq IPv4 | Select-Object InterfaceAlias, IPAddress, PrefixLength | Format-List",
- "systeminfo | findstr /B /C:\"System Boot Time\"",
- }
- }
- // Parse 解析Windows输出
- func (p *WindowsParser) 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 = p.parseUptime(outputs[4])
- device.Interfaces = p.parseInterfaces(outputs[2], outputs[3])
- return nil
- }
- func (p *WindowsParser) parseOSVersion(output string) string {
- lines := strings.Split(output, "\n")
- var osInfo []string
- for _, line := range lines {
- if strings.Contains(line, "OS Name") || strings.Contains(line, "OS Version") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- osInfo = append(osInfo, strings.TrimSpace(parts[1]))
- }
- }
- }
- return strings.Join(osInfo, ", ")
- }
- func (p *WindowsParser) parseUptime(output string) string {
- if strings.Contains(output, "System Boot Time") {
- parts := strings.SplitN(output, ":", 2)
- if len(parts) == 2 {
- return strings.TrimSpace(parts[1])
- }
- }
- return output
- }
- func (p *WindowsParser) parseInterfaces(adapterOutput, ipOutput string) []models.Interface {
- var interfaces []models.Interface
- // 解析网卡信息
- adapters := p.parseNetAdapters(adapterOutput)
-
- // 解析IP信息
- ipMap := p.parseIPAddresses(ipOutput)
- // 合并信息
- for _, adapter := range adapters {
- iface := adapter
- if ipInfo, ok := ipMap[adapter.Name]; ok {
- iface.IP = ipInfo.IP
- iface.Mask = ipInfo.Mask
- }
- interfaces = append(interfaces, iface)
- }
- return interfaces
- }
- func (p *WindowsParser) parseNetAdapters(output string) []models.Interface {
- var interfaces []models.Interface
- var currentInterface *models.Interface
- lines := strings.Split(output, "\n")
- for _, line := range lines {
- line = strings.TrimSpace(line)
- if line == "" {
- continue
- }
- if strings.Contains(line, "Name") && strings.Contains(line, ":") {
- if currentInterface != nil {
- interfaces = append(interfaces, *currentInterface)
- }
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- currentInterface = &models.Interface{
- Name: strings.TrimSpace(parts[1]),
- }
- }
- }
- if currentInterface != nil {
- if strings.Contains(line, "InterfaceDescription") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- currentInterface.Description = strings.TrimSpace(parts[1])
- }
- }
- if strings.Contains(line, "Status") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- status := strings.TrimSpace(parts[1])
- if status == "Up" {
- currentInterface.Status = "up"
- } else {
- currentInterface.Status = "down"
- }
- }
- }
- if strings.Contains(line, "MacAddress") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- currentInterface.MAC = strings.TrimSpace(parts[1])
- }
- }
- if strings.Contains(line, "LinkSpeed") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- currentInterface.Speed = strings.TrimSpace(parts[1])
- }
- }
- }
- }
- if currentInterface != nil {
- interfaces = append(interfaces, *currentInterface)
- }
- return interfaces
- }
- type ipInfo struct {
- IP string
- Mask string
- }
- func (p *WindowsParser) parseIPAddresses(output string) map[string]ipInfo {
- ipMap := make(map[string]ipInfo)
- var currentAlias string
- lines := strings.Split(output, "\n")
- for _, line := range lines {
- line = strings.TrimSpace(line)
- if line == "" {
- continue
- }
- if strings.Contains(line, "InterfaceAlias") {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- currentAlias = strings.TrimSpace(parts[1])
- }
- }
- if strings.Contains(line, "IPAddress") && currentAlias != "" {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- if _, ok := ipMap[currentAlias]; !ok {
- ipMap[currentAlias] = ipInfo{}
- }
- info := ipMap[currentAlias]
- info.IP = strings.TrimSpace(parts[1])
- ipMap[currentAlias] = info
- }
- }
- if strings.Contains(line, "PrefixLength") && currentAlias != "" {
- parts := strings.SplitN(line, ":", 2)
- if len(parts) == 2 {
- if _, ok := ipMap[currentAlias]; !ok {
- ipMap[currentAlias] = ipInfo{}
- }
- info := ipMap[currentAlias]
- info.Mask = strings.TrimSpace(parts[1])
- ipMap[currentAlias] = info
- }
- }
- }
- return ipMap
- }
|