Source file src/vendor/golang.org/x/net/route/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 // +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 } 136