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. 13package route 14 15import ( 16 "errors" 17 "os" 18 "syscall" 19) 20 21var ( 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. 72type RouteMessage struct { 73 Version int // message version 74 Type int // message type 75 Flags int // route flags 76 Index int // interface index when attached 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. 87func (m *RouteMessage) Marshal() ([]byte, error) { 88 return m.marshal() 89} 90 91// A RIBType represents a type of routing information base. 92type RIBType int 93 94const ( 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. 109func 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} 124