123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- // 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 and above, 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")
- errShortBuffer = errors.New("short buffer")
- )
- // A RouteMessage represents a message conveying an address prefix, a
- // nexthop address and an output interface.
- //
- // Unlike other messages, this message can be used to query adjacency
- // information for the given address prefix, to add a new route, and
- // to delete or modify the existing route from the routing information
- // base inside the kernel by writing and reading route messages on a
- // routing socket.
- //
- // For the manipulation of routing information, the route message must
- // contain appropriate fields that include:
- //
- // Version = <must be specified>
- // Type = <must be specified>
- // Flags = <must be specified>
- // Index = <must be specified if necessary>
- // ID = <must be specified>
- // Seq = <must be specified>
- // Addrs = <must be specified>
- //
- // The Type field specifies a type of manipulation, the Flags field
- // specifies a class of target information and the Addrs field
- // specifies target information like the following:
- //
- // route.RouteMessage{
- // Version: RTM_VERSION,
- // Type: RTM_GET,
- // Flags: RTF_UP | RTF_HOST,
- // ID: uintptr(os.Getpid()),
- // Seq: 1,
- // Addrs: []route.Addrs{
- // RTAX_DST: &route.Inet4Addr{ ... },
- // RTAX_IFP: &route.LinkAddr{ ... },
- // RTAX_BRD: &route.Inet4Addr{ ... },
- // },
- // }
- //
- // The values for the above fields depend on the implementation of
- // each operating system.
- //
- // The Err field on a response message contains an error value on the
- // requested operation. If non-nil, the requested operation is failed.
- type RouteMessage struct {
- Version int // message version
- Type int // message type
- Flags int // route flags
- Index int // interface index when attached
- ID uintptr // sender's identifier; usually process ID
- Seq int // sequence number
- Err error // error on requested operation
- Addrs []Addr // addresses
- extOff int // offset of header extension
- raw []byte // raw message
- }
- // Marshal returns the binary encoding of m.
- func (m *RouteMessage) Marshal() ([]byte, error) {
- return m.marshal()
- }
- // A RIBType represents 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
- }
|