gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/net/route/route.go (about)

     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  // +build darwin dragonfly freebsd netbsd openbsd
     7  
     8  // Package route provides basic functions for the manipulation of
     9  // packet routing facilities on BSD variants.
    10  //
    11  // The package supports any version of Darwin, any version of
    12  // DragonFly BSD, FreeBSD 7 and above, NetBSD 6 and above, and OpenBSD
    13  // 5.6 and above.
    14  package route
    15  
    16  import (
    17  	"errors"
    18  	"os"
    19  	"syscall"
    20  )
    21  
    22  var (
    23  	errUnsupportedMessage = errors.New("unsupported message")
    24  	errMessageMismatch    = errors.New("message mismatch")
    25  	errMessageTooShort    = errors.New("message too short")
    26  	errInvalidMessage     = errors.New("invalid message")
    27  	errInvalidAddr        = errors.New("invalid address")
    28  	errShortBuffer        = errors.New("short buffer")
    29  )
    30  
    31  // A RouteMessage represents a message conveying an address prefix, a
    32  // nexthop address and an output interface.
    33  //
    34  // Unlike other messages, this message can be used to query adjacency
    35  // information for the given address prefix, to add a new route, and
    36  // to delete or modify the existing route from the routing information
    37  // base inside the kernel by writing and reading route messages on a
    38  // routing socket.
    39  //
    40  // For the manipulation of routing information, the route message must
    41  // contain appropriate fields that include:
    42  //
    43  //	Version       = <must be specified>
    44  //	Type          = <must be specified>
    45  //	Flags         = <must be specified>
    46  //	Index         = <must be specified if necessary>
    47  //	ID            = <must be specified>
    48  //	Seq           = <must be specified>
    49  //	Addrs         = <must be specified>
    50  //
    51  // The Type field specifies a type of manipulation, the Flags field
    52  // specifies a class of target information and the Addrs field
    53  // specifies target information like the following:
    54  //
    55  //	route.RouteMessage{
    56  //		Version: RTM_VERSION,
    57  //		Type: RTM_GET,
    58  //		Flags: RTF_UP | RTF_HOST,
    59  //		ID: uintptr(os.Getpid()),
    60  //		Seq: 1,
    61  //		Addrs: []route.Addrs{
    62  //			RTAX_DST: &route.Inet4Addr{ ... },
    63  //			RTAX_IFP: &route.LinkAddr{ ... },
    64  //			RTAX_BRD: &route.Inet4Addr{ ... },
    65  //		},
    66  //	}
    67  //
    68  // The values for the above fields depend on the implementation of
    69  // each operating system.
    70  //
    71  // The Err field on a response message contains an error value on the
    72  // requested operation. If non-nil, the requested operation is failed.
    73  type RouteMessage struct {
    74  	Version int     // message version
    75  	Type    int     // message type
    76  	Flags   int     // route flags
    77  	Index   int     // interface index when attached
    78  	ID      uintptr // sender's identifier; usually process ID
    79  	Seq     int     // sequence number
    80  	Err     error   // error on requested operation
    81  	Addrs   []Addr  // addresses
    82  
    83  	extOff int    // offset of header extension
    84  	raw    []byte // raw message
    85  }
    86  
    87  // Marshal returns the binary encoding of m.
    88  func (m *RouteMessage) Marshal() ([]byte, error) {
    89  	return m.marshal()
    90  }
    91  
    92  // A RIBType represents a type of routing information base.
    93  type RIBType int
    94  
    95  const (
    96  	RIBTypeRoute     RIBType = syscall.NET_RT_DUMP
    97  	RIBTypeInterface RIBType = syscall.NET_RT_IFLIST
    98  )
    99  
   100  // FetchRIB fetches a routing information base from the operating
   101  // system.
   102  //
   103  // The provided af must be an address family.
   104  //
   105  // The provided arg must be a RIBType-specific argument.
   106  // When RIBType is related to routes, arg might be a set of route
   107  // flags. When RIBType is related to network interfaces, arg might be
   108  // an interface index or a set of interface flags. In most cases, zero
   109  // means a wildcard.
   110  func FetchRIB(af int, typ RIBType, arg int) ([]byte, error) {
   111  	try := 0
   112  	for {
   113  		try++
   114  		mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)}
   115  		n := uintptr(0)
   116  		if err := sysctl(mib[:], nil, &n, nil, 0); err != nil {
   117  			return nil, os.NewSyscallError("sysctl", err)
   118  		}
   119  		if n == 0 {
   120  			return nil, nil
   121  		}
   122  		b := make([]byte, n)
   123  		if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil {
   124  			// If the sysctl failed because the data got larger
   125  			// between the two sysctl calls, try a few times
   126  			// before failing. (golang.org/issue/45736).
   127  			const maxTries = 3
   128  			if err == syscall.ENOMEM && try < maxTries {
   129  				continue
   130  			}
   131  			return nil, os.NewSyscallError("sysctl", err)
   132  		}
   133  		return b[:n], nil
   134  	}
   135  }