Source file src/internal/routebsd/route.go
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