system_windows.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. //go:build windows
  2. package dns
  3. import (
  4. "net"
  5. "os"
  6. "syscall"
  7. "unsafe"
  8. "golang.org/x/sys/windows"
  9. )
  10. func dnsReadConfig() (servers []string, err error) {
  11. aas, err := adapterAddresses()
  12. if err != nil {
  13. return
  14. }
  15. for _, aa := range aas {
  16. for dns := aa.FirstDnsServerAddress; dns != nil; dns = dns.Next {
  17. sa, err := dns.Address.Sockaddr.Sockaddr()
  18. if err != nil {
  19. continue
  20. }
  21. var ip net.IP
  22. switch sa := sa.(type) {
  23. case *syscall.SockaddrInet4:
  24. ip = net.IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
  25. case *syscall.SockaddrInet6:
  26. ip = make(net.IP, net.IPv6len)
  27. copy(ip, sa.Addr[:])
  28. if ip[0] == 0xfe && ip[1] == 0xc0 {
  29. // Ignore these fec0/10 ones. Windows seems to
  30. // populate them as defaults on its misc rando
  31. // interfaces.
  32. continue
  33. }
  34. //continue
  35. default:
  36. // Unexpected type.
  37. continue
  38. }
  39. servers = append(servers, ip.String())
  40. }
  41. }
  42. return
  43. }
  44. // adapterAddresses returns a list of IP adapter and address
  45. // structures. The structure contains an IP adapter and flattened
  46. // multiple IP addresses including unicast, anycast and multicast
  47. // addresses.
  48. func adapterAddresses() ([]*windows.IpAdapterAddresses, error) {
  49. var b []byte
  50. l := uint32(15000) // recommended initial size
  51. for {
  52. b = make([]byte, l)
  53. err := windows.GetAdaptersAddresses(syscall.AF_UNSPEC, windows.GAA_FLAG_INCLUDE_PREFIX, 0, (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])), &l)
  54. if err == nil {
  55. if l == 0 {
  56. return nil, nil
  57. }
  58. break
  59. }
  60. if err.(syscall.Errno) != syscall.ERROR_BUFFER_OVERFLOW {
  61. return nil, os.NewSyscallError("getadaptersaddresses", err)
  62. }
  63. if l <= uint32(len(b)) {
  64. return nil, os.NewSyscallError("getadaptersaddresses", err)
  65. }
  66. }
  67. var aas []*windows.IpAdapterAddresses
  68. for aa := (*windows.IpAdapterAddresses)(unsafe.Pointer(&b[0])); aa != nil; aa = aa.Next {
  69. aas = append(aas, aa)
  70. }
  71. return aas, nil
  72. }