summaryrefslogtreecommitdiff
path: root/src/pkg/net/lookup_windows.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/lookup_windows.go')
-rw-r--r--src/pkg/net/lookup_windows.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/src/pkg/net/lookup_windows.go b/src/pkg/net/lookup_windows.go
new file mode 100644
index 000000000..fa3ad7c7f
--- /dev/null
+++ b/src/pkg/net/lookup_windows.go
@@ -0,0 +1,130 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package net
+
+import (
+ "syscall"
+ "unsafe"
+ "os"
+ "sync"
+)
+
+var hostentLock sync.Mutex
+var serventLock sync.Mutex
+
+func LookupHost(name string) (addrs []string, err os.Error) {
+ ips, err := LookupIP(name)
+ if err != nil {
+ return
+ }
+ addrs = make([]string, 0, len(ips))
+ for _, ip := range ips {
+ addrs = append(addrs, ip.String())
+ }
+ return
+}
+
+func LookupIP(name string) (addrs []IP, err os.Error) {
+ hostentLock.Lock()
+ defer hostentLock.Unlock()
+ h, e := syscall.GetHostByName(name)
+ if e != 0 {
+ return nil, os.NewSyscallError("GetHostByName", e)
+ }
+ switch h.AddrType {
+ case syscall.AF_INET:
+ i := 0
+ addrs = make([]IP, 100) // plenty of room to grow
+ for p := (*[100](*[4]byte))(unsafe.Pointer(h.AddrList)); i < cap(addrs) && p[i] != nil; i++ {
+ addrs[i] = IPv4(p[i][0], p[i][1], p[i][2], p[i][3])
+ }
+ addrs = addrs[0:i]
+ default: // TODO(vcc): Implement non IPv4 address lookups.
+ return nil, os.NewSyscallError("LookupHost", syscall.EWINDOWS)
+ }
+ return addrs, nil
+}
+
+func LookupPort(network, service string) (port int, err os.Error) {
+ switch network {
+ case "tcp4", "tcp6":
+ network = "tcp"
+ case "udp4", "udp6":
+ network = "udp"
+ }
+ serventLock.Lock()
+ defer serventLock.Unlock()
+ s, e := syscall.GetServByName(service, network)
+ if e != 0 {
+ return 0, os.NewSyscallError("GetServByName", e)
+ }
+ return int(syscall.Ntohs(s.Port)), nil
+}
+
+func LookupCNAME(name string) (cname string, err os.Error) {
+ var r *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_CNAME, 0, nil, &r, nil)
+ if int(e) != 0 {
+ return "", os.NewSyscallError("LookupCNAME", int(e))
+ }
+ defer syscall.DnsRecordListFree(r, 1)
+ if r != nil && r.Type == syscall.DNS_TYPE_CNAME {
+ v := (*syscall.DNSPTRData)(unsafe.Pointer(&r.Data[0]))
+ cname = syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]) + "."
+ }
+ return
+}
+
+func LookupSRV(service, proto, name string) (cname string, addrs []*SRV, err os.Error) {
+ var r *syscall.DNSRecord
+ target := "_" + service + "._" + proto + "." + name
+ e := syscall.DnsQuery(target, syscall.DNS_TYPE_SRV, 0, nil, &r, nil)
+ if int(e) != 0 {
+ return "", nil, os.NewSyscallError("LookupSRV", int(e))
+ }
+ defer syscall.DnsRecordListFree(r, 1)
+ addrs = make([]*SRV, 0, 10)
+ for p := r; p != nil && p.Type == syscall.DNS_TYPE_SRV; p = p.Next {
+ v := (*syscall.DNSSRVData)(unsafe.Pointer(&p.Data[0]))
+ addrs = append(addrs, &SRV{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Target))[:]), v.Port, v.Priority, v.Weight})
+ }
+ byPriorityWeight(addrs).sort()
+ return name, addrs, nil
+}
+
+func LookupMX(name string) (mx []*MX, err os.Error) {
+ var r *syscall.DNSRecord
+ e := syscall.DnsQuery(name, syscall.DNS_TYPE_MX, 0, nil, &r, nil)
+ if int(e) != 0 {
+ return nil, os.NewSyscallError("LookupMX", int(e))
+ }
+ defer syscall.DnsRecordListFree(r, 1)
+ mx = make([]*MX, 0, 10)
+ for p := r; p != nil && p.Type == syscall.DNS_TYPE_MX; p = p.Next {
+ v := (*syscall.DNSMXData)(unsafe.Pointer(&p.Data[0]))
+ mx = append(mx, &MX{syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.NameExchange))[:]) + ".", v.Preference})
+ }
+ byPref(mx).sort()
+ return mx, nil
+}
+
+func LookupAddr(addr string) (name []string, err os.Error) {
+ arpa, err := reverseaddr(addr)
+ if err != nil {
+ return nil, err
+ }
+ var r *syscall.DNSRecord
+ e := syscall.DnsQuery(arpa, syscall.DNS_TYPE_PTR, 0, nil, &r, nil)
+ if int(e) != 0 {
+ return nil, os.NewSyscallError("LookupAddr", int(e))
+ }
+ defer syscall.DnsRecordListFree(r, 1)
+ name = make([]string, 0, 10)
+ for p := r; p != nil && p.Type == syscall.DNS_TYPE_PTR; p = p.Next {
+ v := (*syscall.DNSPTRData)(unsafe.Pointer(&p.Data[0]))
+ name = append(name, syscall.UTF16ToString((*[256]uint16)(unsafe.Pointer(v.Host))[:]))
+ }
+ return name, nil
+}