windows.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. package device
  2. import (
  3. "fmt"
  4. "network-topology-discovery/pkg/models"
  5. "strings"
  6. )
  7. // WindowsParser Windows Server解析器
  8. type WindowsParser struct {
  9. BaseParser
  10. }
  11. // GetCommands 获取Windows命令列表
  12. func (p *WindowsParser) GetCommands() []string {
  13. return []string{
  14. "hostname",
  15. "systeminfo | findstr /B /C:\"OS Name\" /C:\"OS Version\"",
  16. "Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, MacAddress, LinkSpeed | Format-List",
  17. "Get-NetIPAddress | Where-Object AddressFamily -eq IPv4 | Select-Object InterfaceAlias, IPAddress, PrefixLength | Format-List",
  18. "systeminfo | findstr /B /C:\"System Boot Time\"",
  19. }
  20. }
  21. // Parse 解析Windows输出
  22. func (p *WindowsParser) Parse(device *models.Device, outputs []string) error {
  23. if len(outputs) < 5 {
  24. return fmt.Errorf("insufficient command outputs")
  25. }
  26. device.Hostname = strings.TrimSpace(outputs[0])
  27. device.OSVersion = p.parseOSVersion(outputs[1])
  28. device.Uptime = p.parseUptime(outputs[4])
  29. device.Interfaces = p.parseInterfaces(outputs[2], outputs[3])
  30. return nil
  31. }
  32. func (p *WindowsParser) parseOSVersion(output string) string {
  33. lines := strings.Split(output, "\n")
  34. var osInfo []string
  35. for _, line := range lines {
  36. if strings.Contains(line, "OS Name") || strings.Contains(line, "OS Version") {
  37. parts := strings.SplitN(line, ":", 2)
  38. if len(parts) == 2 {
  39. osInfo = append(osInfo, strings.TrimSpace(parts[1]))
  40. }
  41. }
  42. }
  43. return strings.Join(osInfo, ", ")
  44. }
  45. func (p *WindowsParser) parseUptime(output string) string {
  46. if strings.Contains(output, "System Boot Time") {
  47. parts := strings.SplitN(output, ":", 2)
  48. if len(parts) == 2 {
  49. return strings.TrimSpace(parts[1])
  50. }
  51. }
  52. return output
  53. }
  54. func (p *WindowsParser) parseInterfaces(adapterOutput, ipOutput string) []models.Interface {
  55. var interfaces []models.Interface
  56. // 解析网卡信息
  57. adapters := p.parseNetAdapters(adapterOutput)
  58. // 解析IP信息
  59. ipMap := p.parseIPAddresses(ipOutput)
  60. // 合并信息
  61. for _, adapter := range adapters {
  62. iface := adapter
  63. if ipInfo, ok := ipMap[adapter.Name]; ok {
  64. iface.IP = ipInfo.IP
  65. iface.Mask = ipInfo.Mask
  66. }
  67. interfaces = append(interfaces, iface)
  68. }
  69. return interfaces
  70. }
  71. func (p *WindowsParser) parseNetAdapters(output string) []models.Interface {
  72. var interfaces []models.Interface
  73. var currentInterface *models.Interface
  74. lines := strings.Split(output, "\n")
  75. for _, line := range lines {
  76. line = strings.TrimSpace(line)
  77. if line == "" {
  78. continue
  79. }
  80. if strings.Contains(line, "Name") && strings.Contains(line, ":") {
  81. if currentInterface != nil {
  82. interfaces = append(interfaces, *currentInterface)
  83. }
  84. parts := strings.SplitN(line, ":", 2)
  85. if len(parts) == 2 {
  86. currentInterface = &models.Interface{
  87. Name: strings.TrimSpace(parts[1]),
  88. }
  89. }
  90. }
  91. if currentInterface != nil {
  92. if strings.Contains(line, "InterfaceDescription") {
  93. parts := strings.SplitN(line, ":", 2)
  94. if len(parts) == 2 {
  95. currentInterface.Description = strings.TrimSpace(parts[1])
  96. }
  97. }
  98. if strings.Contains(line, "Status") {
  99. parts := strings.SplitN(line, ":", 2)
  100. if len(parts) == 2 {
  101. status := strings.TrimSpace(parts[1])
  102. if status == "Up" {
  103. currentInterface.Status = "up"
  104. } else {
  105. currentInterface.Status = "down"
  106. }
  107. }
  108. }
  109. if strings.Contains(line, "MacAddress") {
  110. parts := strings.SplitN(line, ":", 2)
  111. if len(parts) == 2 {
  112. currentInterface.MAC = strings.TrimSpace(parts[1])
  113. }
  114. }
  115. if strings.Contains(line, "LinkSpeed") {
  116. parts := strings.SplitN(line, ":", 2)
  117. if len(parts) == 2 {
  118. currentInterface.Speed = strings.TrimSpace(parts[1])
  119. }
  120. }
  121. }
  122. }
  123. if currentInterface != nil {
  124. interfaces = append(interfaces, *currentInterface)
  125. }
  126. return interfaces
  127. }
  128. type ipInfo struct {
  129. IP string
  130. Mask string
  131. }
  132. func (p *WindowsParser) parseIPAddresses(output string) map[string]ipInfo {
  133. ipMap := make(map[string]ipInfo)
  134. var currentAlias string
  135. lines := strings.Split(output, "\n")
  136. for _, line := range lines {
  137. line = strings.TrimSpace(line)
  138. if line == "" {
  139. continue
  140. }
  141. if strings.Contains(line, "InterfaceAlias") {
  142. parts := strings.SplitN(line, ":", 2)
  143. if len(parts) == 2 {
  144. currentAlias = strings.TrimSpace(parts[1])
  145. }
  146. }
  147. if strings.Contains(line, "IPAddress") && currentAlias != "" {
  148. parts := strings.SplitN(line, ":", 2)
  149. if len(parts) == 2 {
  150. if _, ok := ipMap[currentAlias]; !ok {
  151. ipMap[currentAlias] = ipInfo{}
  152. }
  153. info := ipMap[currentAlias]
  154. info.IP = strings.TrimSpace(parts[1])
  155. ipMap[currentAlias] = info
  156. }
  157. }
  158. if strings.Contains(line, "PrefixLength") && currentAlias != "" {
  159. parts := strings.SplitN(line, ":", 2)
  160. if len(parts) == 2 {
  161. if _, ok := ipMap[currentAlias]; !ok {
  162. ipMap[currentAlias] = ipInfo{}
  163. }
  164. info := ipMap[currentAlias]
  165. info.Mask = strings.TrimSpace(parts[1])
  166. ipMap[currentAlias] = info
  167. }
  168. }
  169. }
  170. return ipMap
  171. }