diff options
Diffstat (limited to 'src/net/lookup_unix.go')
-rw-r--r-- | src/net/lookup_unix.go | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/net/lookup_unix.go b/src/net/lookup_unix.go new file mode 100644 index 000000000..a54578456 --- /dev/null +++ b/src/net/lookup_unix.go @@ -0,0 +1,168 @@ +// Copyright 2011 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd solaris + +package net + +import ( + "errors" + "sync" +) + +var onceReadProtocols sync.Once + +// readProtocols loads contents of /etc/protocols into protocols map +// for quick access. +func readProtocols() { + if file, err := open("/etc/protocols"); err == nil { + for line, ok := file.readLine(); ok; line, ok = file.readLine() { + // tcp 6 TCP # transmission control protocol + if i := byteIndex(line, '#'); i >= 0 { + line = line[0:i] + } + f := getFields(line) + if len(f) < 2 { + continue + } + if proto, _, ok := dtoi(f[1], 0); ok { + if _, ok := protocols[f[0]]; !ok { + protocols[f[0]] = proto + } + for _, alias := range f[2:] { + if _, ok := protocols[alias]; !ok { + protocols[alias] = proto + } + } + } + } + file.close() + } +} + +// lookupProtocol looks up IP protocol name in /etc/protocols and +// returns correspondent protocol number. +func lookupProtocol(name string) (proto int, err error) { + onceReadProtocols.Do(readProtocols) + proto, found := protocols[name] + if !found { + return 0, errors.New("unknown IP protocol specified: " + name) + } + return +} + +func lookupHost(host string) (addrs []string, err error) { + addrs, err, ok := cgoLookupHost(host) + if !ok { + addrs, err = goLookupHost(host) + } + return +} + +func lookupIP(host string) (addrs []IP, err error) { + addrs, err, ok := cgoLookupIP(host) + if !ok { + addrs, err = goLookupIP(host) + } + return +} + +func lookupPort(network, service string) (port int, err error) { + port, err, ok := cgoLookupPort(network, service) + if !ok { + port, err = goLookupPort(network, service) + } + return +} + +func lookupCNAME(name string) (cname string, err error) { + cname, err, ok := cgoLookupCNAME(name) + if !ok { + cname, err = goLookupCNAME(name) + } + return +} + +func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { + var target string + if service == "" && proto == "" { + target = name + } else { + target = "_" + service + "._" + proto + "." + name + } + var records []dnsRR + cname, records, err = lookup(target, dnsTypeSRV) + if err != nil { + return + } + addrs = make([]*SRV, len(records)) + for i, rr := range records { + r := rr.(*dnsRR_SRV) + addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight} + } + byPriorityWeight(addrs).sort() + return +} + +func lookupMX(name string) (mx []*MX, err error) { + _, records, err := lookup(name, dnsTypeMX) + if err != nil { + return + } + mx = make([]*MX, len(records)) + for i, rr := range records { + r := rr.(*dnsRR_MX) + mx[i] = &MX{r.Mx, r.Pref} + } + byPref(mx).sort() + return +} + +func lookupNS(name string) (ns []*NS, err error) { + _, records, err := lookup(name, dnsTypeNS) + if err != nil { + return + } + ns = make([]*NS, len(records)) + for i, r := range records { + r := r.(*dnsRR_NS) + ns[i] = &NS{r.Ns} + } + return +} + +func lookupTXT(name string) (txt []string, err error) { + _, records, err := lookup(name, dnsTypeTXT) + if err != nil { + return + } + txt = make([]string, len(records)) + for i, r := range records { + txt[i] = r.(*dnsRR_TXT).Txt + } + return +} + +func lookupAddr(addr string) (name []string, err error) { + name = lookupStaticAddr(addr) + if len(name) > 0 { + return + } + var arpa string + arpa, err = reverseaddr(addr) + if err != nil { + return + } + var records []dnsRR + _, records, err = lookup(arpa, dnsTypePTR) + if err != nil { + return + } + name = make([]string, len(records)) + for i := range records { + r := records[i].(*dnsRR_PTR) + name[i] = r.Ptr + } + return +} |