1// Copyright 2009 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 dragonfly freebsd linux netbsd openbsd solaris nacl
6
7// Read system port mappings from /etc/services
8
9package net
10
11import "sync"
12
13var onceReadServices sync.Once
14
15func readServices() {
16	file, err := open("/etc/services")
17	if err != nil {
18		return
19	}
20	defer file.close()
21
22	for line, ok := file.readLine(); ok; line, ok = file.readLine() {
23		// "http 80/tcp www www-http # World Wide Web HTTP"
24		if i := byteIndex(line, '#'); i >= 0 {
25			line = line[:i]
26		}
27		f := getFields(line)
28		if len(f) < 2 {
29			continue
30		}
31		portnet := f[1] // "80/tcp"
32		port, j, ok := dtoi(portnet)
33		if !ok || port <= 0 || j >= len(portnet) || portnet[j] != '/' {
34			continue
35		}
36		netw := portnet[j+1:] // "tcp"
37		m, ok1 := services[netw]
38		if !ok1 {
39			m = make(map[string]int)
40			services[netw] = m
41		}
42		for i := 0; i < len(f); i++ {
43			if i != 1 { // f[1] was port/net
44				m[f[i]] = port
45			}
46		}
47	}
48}
49
50// goLookupPort is the native Go implementation of LookupPort.
51func goLookupPort(network, service string) (port int, err error) {
52	onceReadServices.Do(readServices)
53	return lookupPortMap(network, service)
54}
55