// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // +build darwin dragonfly freebsd netbsd openbsd // Package route provides basic functions for the manipulation of // packet routing facilities on BSD variants. // // The package supports any version of Darwin, any version of // DragonFly BSD, FreeBSD 7 through 11, NetBSD 6 and above, and // OpenBSD 5.6 and above. package route import ( "errors" "os" "syscall" ) var ( errUnsupportedMessage = errors.New("unsupported message") errMessageMismatch = errors.New("message mismatch") errMessageTooShort = errors.New("message too short") errInvalidMessage = errors.New("invalid message") errInvalidAddr = errors.New("invalid address") ) // A RouteMessage represents a message conveying an address prefix, a // nexthop address and an output interface. type RouteMessage struct { Version int // message version Type int // message type Flags int // route flags Index int // interface index when atatched Addrs []Addr // addresses extOff int // offset of header extension raw []byte // raw message } // A RIBType reprensents a type of routing information base. type RIBType int const ( RIBTypeRoute RIBType = syscall.NET_RT_DUMP RIBTypeInterface RIBType = syscall.NET_RT_IFLIST ) // FetchRIB fetches a routing information base from the operating // system. // // The provided af must be an address family. // // The provided arg must be a RIBType-specific argument. // When RIBType is related to routes, arg might be a set of route // flags. When RIBType is related to network interfaces, arg might be // an interface index or a set of interface flags. In most cases, zero // means a wildcard. func FetchRIB(af int, typ RIBType, arg int) ([]byte, error) { mib := [6]int32{sysCTL_NET, sysAF_ROUTE, 0, int32(af), int32(typ), int32(arg)} n := uintptr(0) if err := sysctl(mib[:], nil, &n, nil, 0); err != nil { return nil, os.NewSyscallError("sysctl", err) } if n == 0 { return nil, nil } b := make([]byte, n) if err := sysctl(mib[:], &b[0], &n, nil, 0); err != nil { return nil, os.NewSyscallError("sysctl", err) } return b[:n], nil }