1 // Copyright 2016 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 //go:build darwin || dragonfly || freebsd || netbsd || openbsd
6 7 // Package routebsd supports reading interface addresses on BSD systems.
8 // This is a very stripped down version of x/net/route,
9 // for use by the net package in the standard library.
10 package routebsd
11 12 import (
13 "errors"
14 "syscall"
15 )
16 17 var (
18 errMessageMismatch = errors.New("message mismatch")
19 errMessageTooShort = errors.New("message too short")
20 errInvalidMessage = errors.New("invalid message")
21 errInvalidAddr = errors.New("invalid address")
22 )
23 24 // fetchRIB fetches a routing information base from the operating
25 // system.
26 //
27 // The arg is an interface index or 0 for all.
28 func fetchRIB(typ, arg int) ([]byte, error) {
29 try := 0
30 for {
31 try++
32 b, err := syscall.RouteRIB(typ, arg)
33 34 // If the sysctl failed because the data got larger
35 // between the two sysctl calls, try a few times
36 // before failing (issue #45736).
37 const maxTries = 3
38 if err == syscall.ENOMEM && try < maxTries {
39 continue
40 }
41 42 return b, err
43 }
44 }
45 46 // FetchRIBMessages fetches a list of addressing messages for an interface.
47 // The typ argument is something like syscall.NET_RT_IFLIST.
48 // The argument is an interface index or 0 for all.
49 func FetchRIBMessages(typ, arg int) ([]Message, error) {
50 b, err := fetchRIB(typ, arg)
51 if err != nil {
52 return nil, err
53 }
54 ms, err := parseRIB(b)
55 if err != nil {
56 return nil, err
57 }
58 return ms, nil
59 }
60