configreader.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. package configreader
  2. import (
  3. "bufio"
  4. "fmt"
  5. "net"
  6. "os"
  7. "os/exec"
  8. "strings"
  9. "quickip/internal/model"
  10. )
  11. type Service struct{}
  12. func New() *Service { return &Service{} }
  13. func (s *Service) Read(interfaceName string) (model.InterfaceConfig, error) {
  14. iface, err := net.InterfaceByName(interfaceName)
  15. if err != nil {
  16. return model.InterfaceConfig{}, err
  17. }
  18. config := model.InterfaceConfig{Interface: interfaceName, DNS: []string{}}
  19. addrs, err := iface.Addrs()
  20. if err != nil {
  21. return model.InterfaceConfig{}, err
  22. }
  23. for _, addr := range addrs {
  24. ipNet, ok := addr.(*net.IPNet)
  25. if !ok || ipNet.IP.To4() == nil {
  26. continue
  27. }
  28. config.IP = ipNet.IP.String()
  29. config.Prefix, _ = ipNet.Mask.Size()
  30. break
  31. }
  32. config.Gateway = readGateway(interfaceName)
  33. config.DNS = readDNS()
  34. return config, nil
  35. }
  36. func readGateway(interfaceName string) string {
  37. cmd := exec.Command("ip", "route", "show", "dev", interfaceName)
  38. output, err := cmd.Output()
  39. if err != nil {
  40. return ""
  41. }
  42. for _, line := range strings.Split(string(output), "\n") {
  43. line = strings.TrimSpace(line)
  44. if !strings.HasPrefix(line, "default via ") {
  45. continue
  46. }
  47. parts := strings.Fields(line)
  48. if len(parts) >= 3 {
  49. return parts[2]
  50. }
  51. }
  52. return ""
  53. }
  54. func readDNS() []string {
  55. file, err := os.Open("/etc/resolv.conf")
  56. if err != nil {
  57. return []string{}
  58. }
  59. defer file.Close()
  60. result := make([]string, 0, 2)
  61. scanner := bufio.NewScanner(file)
  62. for scanner.Scan() {
  63. line := strings.TrimSpace(scanner.Text())
  64. if !strings.HasPrefix(line, "nameserver ") {
  65. continue
  66. }
  67. parts := strings.Fields(line)
  68. if len(parts) >= 2 {
  69. result = append(result, parts[1])
  70. }
  71. }
  72. return result
  73. }
  74. func MustRead(interfaceName string) model.InterfaceConfig {
  75. config, err := New().Read(interfaceName)
  76. if err != nil {
  77. panic(fmt.Sprintf("read interface config failed: %v", err))
  78. }
  79. return config
  80. }