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  

View as plain text