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