Source file src/pkg/net/lookup_unix.go
1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build darwin freebsd linux netbsd openbsd 6 7 package net 8 9 import ( 10 "errors" 11 "sync" 12 ) 13 14 var ( 15 protocols map[string]int 16 onceReadProtocols sync.Once 17 ) 18 19 // readProtocols loads contents of /etc/protocols into protocols map 20 // for quick access. 21 func readProtocols() { 22 protocols = make(map[string]int) 23 if file, err := open("/etc/protocols"); err == nil { 24 for line, ok := file.readLine(); ok; line, ok = file.readLine() { 25 // tcp 6 TCP # transmission control protocol 26 if i := byteIndex(line, '#'); i >= 0 { 27 line = line[0:i] 28 } 29 f := getFields(line) 30 if len(f) < 2 { 31 continue 32 } 33 if proto, _, ok := dtoi(f[1], 0); ok { 34 protocols[f[0]] = proto 35 for _, alias := range f[2:] { 36 protocols[alias] = proto 37 } 38 } 39 } 40 file.close() 41 } 42 } 43 44 // lookupProtocol looks up IP protocol name in /etc/protocols and 45 // returns correspondent protocol number. 46 func lookupProtocol(name string) (proto int, err error) { 47 onceReadProtocols.Do(readProtocols) 48 proto, found := protocols[name] 49 if !found { 50 return 0, errors.New("unknown IP protocol specified: " + name) 51 } 52 return 53 } 54 55 func lookupHost(host string) (addrs []string, err error) { 56 addrs, err, ok := cgoLookupHost(host) 57 if !ok { 58 addrs, err = goLookupHost(host) 59 } 60 return 61 } 62 63 func lookupIP(host string) (addrs []IP, err error) { 64 addrs, err, ok := cgoLookupIP(host) 65 if !ok { 66 addrs, err = goLookupIP(host) 67 } 68 return 69 } 70 71 func lookupPort(network, service string) (port int, err error) { 72 port, err, ok := cgoLookupPort(network, service) 73 if !ok { 74 port, err = goLookupPort(network, service) 75 } 76 return 77 } 78 79 func lookupCNAME(name string) (cname string, err error) { 80 cname, err, ok := cgoLookupCNAME(name) 81 if !ok { 82 cname, err = goLookupCNAME(name) 83 } 84 return 85 } 86 87 func lookupSRV(service, proto, name string) (cname string, addrs []*SRV, err error) { 88 var target string 89 if service == "" && proto == "" { 90 target = name 91 } else { 92 target = "_" + service + "._" + proto + "." + name 93 } 94 var records []dnsRR 95 cname, records, err = lookup(target, dnsTypeSRV) 96 if err != nil { 97 return 98 } 99 addrs = make([]*SRV, len(records)) 100 for i, rr := range records { 101 r := rr.(*dnsRR_SRV) 102 addrs[i] = &SRV{r.Target, r.Port, r.Priority, r.Weight} 103 } 104 byPriorityWeight(addrs).sort() 105 return 106 } 107 108 func lookupMX(name string) (mx []*MX, err error) { 109 _, records, err := lookup(name, dnsTypeMX) 110 if err != nil { 111 return 112 } 113 mx = make([]*MX, len(records)) 114 for i, rr := range records { 115 r := rr.(*dnsRR_MX) 116 mx[i] = &MX{r.Mx, r.Pref} 117 } 118 byPref(mx).sort() 119 return 120 } 121 122 func lookupTXT(name string) (txt []string, err error) { 123 _, records, err := lookup(name, dnsTypeTXT) 124 if err != nil { 125 return 126 } 127 txt = make([]string, len(records)) 128 for i, r := range records { 129 txt[i] = r.(*dnsRR_TXT).Txt 130 } 131 return 132 } 133 134 func lookupAddr(addr string) (name []string, err error) { 135 name = lookupStaticAddr(addr) 136 if len(name) > 0 { 137 return 138 } 139 var arpa string 140 arpa, err = reverseaddr(addr) 141 if err != nil { 142 return 143 } 144 var records []dnsRR 145 _, records, err = lookup(arpa, dnsTypePTR) 146 if err != nil { 147 return 148 } 149 name = make([]string, len(records)) 150 for i := range records { 151 r := records[i].(*dnsRR_PTR) 152 name[i] = r.Ptr 153 } 154 return 155 }