summaryrefslogtreecommitdiff
path: root/vendor/golang.org/x/net/route/route.go
blob: 081da0d5c18f3f00907468decba8ead93393fa74 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// 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")
	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 atatched
	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 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
}