asa.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package device
  2. import (
  3. "bufio"
  4. "fmt"
  5. "network-topology-discovery/pkg/models"
  6. "regexp"
  7. "strings"
  8. )
  9. // ASAParser ASA防火墙解析器
  10. type ASAParser struct {
  11. BaseParser
  12. }
  13. // GetCommands 获取ASA设备命令列表
  14. func (p *ASAParser) GetCommands() []string {
  15. return []string{
  16. "show version",
  17. "show interface",
  18. "show ip",
  19. "show inventory",
  20. }
  21. }
  22. // Parse 解析ASA设备输出
  23. func (p *ASAParser) Parse(device *models.Device, outputs []string) error {
  24. if len(outputs) < 4 {
  25. return fmt.Errorf("insufficient command outputs")
  26. }
  27. p.parseVersion(device, outputs[0])
  28. device.Interfaces = p.parseInterfaces(outputs[1])
  29. return nil
  30. }
  31. func (p *ASAParser) parseVersion(device *models.Device, output string) {
  32. hostnameRegex := regexp.MustCompile(`^(\S+)\s*>`)
  33. lines := strings.Split(output, "\n")
  34. for _, line := range lines {
  35. if matches := hostnameRegex.FindStringSubmatch(line); len(matches) > 1 {
  36. device.Hostname = matches[1]
  37. break
  38. }
  39. }
  40. if strings.Contains(output, "ASA Version") {
  41. lines := strings.Split(output, "\n")
  42. for _, line := range lines {
  43. if strings.Contains(line, "ASA Version") {
  44. device.OSVersion = strings.TrimSpace(line)
  45. break
  46. }
  47. }
  48. }
  49. uptimeRegex := regexp.MustCompile(`up\s+\d+\s+hours?\s+\d+\s+mins?`)
  50. if matches := uptimeRegex.FindString(output); matches != "" {
  51. device.Uptime = matches
  52. }
  53. }
  54. func (p *ASAParser) parseInterfaces(output string) []models.Interface {
  55. var interfaces []models.Interface
  56. scanner := bufio.NewScanner(strings.NewReader(output))
  57. var currentInterface *models.Interface
  58. for scanner.Scan() {
  59. line := scanner.Text()
  60. if nameRegex := regexp.MustCompile(`^Interface\s+(\S+)\s+"(\S+)"`); nameRegex.MatchString(line) {
  61. if currentInterface != nil {
  62. interfaces = append(interfaces, *currentInterface)
  63. }
  64. matches := nameRegex.FindStringSubmatch(line)
  65. currentInterface = &models.Interface{
  66. Name: matches[1],
  67. Description: matches[2],
  68. }
  69. }
  70. if currentInterface != nil {
  71. if statusRegex := regexp.MustCompile(`\S+\s+is\s+(up|down)`); statusRegex.MatchString(line) {
  72. matches := statusRegex.FindStringSubmatch(line)
  73. currentInterface.Status = matches[1]
  74. }
  75. if macRegex := regexp.MustCompile(`Hardware is\s+\S+,\s+address is\s+(\S+)`); macRegex.MatchString(line) {
  76. matches := macRegex.FindStringSubmatch(line)
  77. currentInterface.MAC = matches[1]
  78. }
  79. if ipRegex := regexp.MustCompile(`IP address\s+(\d+\.\d+\.\d+\.\d+),\s+subnet mask\s+(\d+\.\d+\.\d+\.\d+)`); ipRegex.MatchString(line) {
  80. matches := ipRegex.FindStringSubmatch(line)
  81. currentInterface.IP = matches[1]
  82. currentInterface.Mask = matches[2]
  83. }
  84. if speedRegex := regexp.MustCompile(`(\d+)\s+(Mbps|Gbps)`); speedRegex.MatchString(line) {
  85. matches := speedRegex.FindStringSubmatch(line)
  86. currentInterface.Speed = matches[1] + " " + matches[2]
  87. }
  88. }
  89. }
  90. if currentInterface != nil {
  91. interfaces = append(interfaces, *currentInterface)
  92. }
  93. return interfaces
  94. }