mirror of https://github.com/golang/go.git
net, internal/routebsd: move vendored x/net/route to internal
This is a simple move of the contents of the vendored x/net/route to internal/routebsd. I've also added some test files that were not previously vendored. This next CL will simplify the new internal/routebsd, removing the code that is not needed by the new package. This is a step toward simplifying the x/net/route package by permitting it to import x/sys/unix. Change-Id: I4d13df11fa9738cd68876b2ea456d03f82d8d64a Reviewed-on: https://go-review.googlesource.com/c/go/+/637695 Commit-Queue: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Commit-Queue: Ian Lance Taylor <iant@golang.org> Auto-Submit: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@golang.org> Reviewed-by: Damien Neil <dneil@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
41298239cf
commit
c1a5889edb
|
|
@ -388,12 +388,14 @@ var depsRules = `
|
|||
|
||||
os
|
||||
< golang.org/x/net/dns/dnsmessage,
|
||||
golang.org/x/net/lif,
|
||||
golang.org/x/net/route;
|
||||
golang.org/x/net/lif;
|
||||
|
||||
internal/bytealg, internal/itoa, math/bits, slices, strconv, unique
|
||||
< net/netip;
|
||||
|
||||
os, net/netip
|
||||
< internal/routebsd;
|
||||
|
||||
# net is unavoidable when doing any networking,
|
||||
# so large dependencies must be kept out.
|
||||
# This is a long-looking list but most of these
|
||||
|
|
@ -401,10 +403,10 @@ var depsRules = `
|
|||
CGO,
|
||||
golang.org/x/net/dns/dnsmessage,
|
||||
golang.org/x/net/lif,
|
||||
golang.org/x/net/route,
|
||||
internal/godebug,
|
||||
internal/nettrace,
|
||||
internal/poll,
|
||||
internal/routebsd,
|
||||
internal/singleflight,
|
||||
net/netip,
|
||||
os,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
// 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.
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type parseAddrsOnDarwinTest struct {
|
||||
attrs uint
|
||||
fn func(int, []byte) (int, Addr, error)
|
||||
b []byte
|
||||
as []Addr
|
||||
}
|
||||
|
||||
var parseAddrsOnDarwinLittleEndianTests = []parseAddrsOnDarwinTest{
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x10, 0x2, 0x0, 0x0, 0xc0, 0xa8, 0x56, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x14, 0x12, 0x4, 0x0, 0x6, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
},
|
||||
[]Addr{
|
||||
&Inet4Addr{IP: [4]byte{192, 168, 86, 0}},
|
||||
&LinkAddr{Index: 4},
|
||||
&Inet4Addr{IP: [4]byte{255, 255, 255, 255}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x10, 0x02, 0x00, 0x00, 0x64, 0x71, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x14, 0x12, 0x21, 0x00, 0x01, 0x08, 0x00, 0x00,
|
||||
0x75, 0x74, 0x75, 0x6e, 0x34, 0x33, 0x31, 0x39,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x06, 0x02, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
},
|
||||
[]Addr{
|
||||
&Inet4Addr{IP: [4]byte{100, 113, 0, 0}},
|
||||
&LinkAddr{Index: 33, Name: "utun4319"},
|
||||
&Inet4Addr{IP: [4]byte{255, 255, 0, 0}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
// route -n add -inet6 fd84:1b4e:6281:: -prefixlen 48 fe80::f22f:4bff:fe09:3bff%utun4319
|
||||
// gw fe80:0000:0000:0000:f22f:4bff:fe09:3bff
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfd, 0x84, 0x1b, 0x4e, 0x62, 0x81, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfe, 0x80, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x0e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
},
|
||||
[]Addr{
|
||||
&Inet6Addr{IP: [16]byte{0xfd, 0x84, 0x1b, 0x4e, 0x62, 0x81}},
|
||||
&Inet6Addr{IP: [16]byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff}, ZoneID: 33},
|
||||
&Inet6Addr{IP: [16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
// golang/go#70528, the kernel can produce addresses of length 0
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x00, 0x1e, 0x00, 0x00,
|
||||
|
||||
0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xfe, 0x80, 0x00, 0x21, 0x00, 0x00, 0x00, 0x00,
|
||||
0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x0e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
|
||||
},
|
||||
[]Addr{
|
||||
nil,
|
||||
&Inet6Addr{IP: [16]byte{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x2f, 0x4b, 0xff, 0xfe, 0x09, 0x3b, 0xff}, ZoneID: 33},
|
||||
&Inet6Addr{IP: [16]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
// Additional case: golang/go/issues/70528#issuecomment-2498692877
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x84, 0x00, 0x05, 0x04, 0x01, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, 0x01, 0x15, 0x00, 0x00, 0x00,
|
||||
0x1B, 0x01, 0x00, 0x00, 0xF5, 0x5A, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
|
||||
0x14, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
},
|
||||
[]Addr{
|
||||
&Inet4Addr{IP: [4]byte{0x0, 0x0, 0x0, 0x0}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseAddrsOnDarwin(t *testing.T) {
|
||||
tests := parseAddrsOnDarwinLittleEndianTests
|
||||
if nativeEndian != littleEndian {
|
||||
t.Skip("no test for non-little endian machine yet")
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
as, err := parseAddrs(tt.attrs, tt.fn, tt.b)
|
||||
if err != nil {
|
||||
t.Error(i, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(as, tt.as) {
|
||||
t.Errorf("#%d: got %+v; want %+v", i, as, tt.as)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
// 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.
|
||||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type parseAddrsTest struct {
|
||||
attrs uint
|
||||
fn func(int, []byte) (int, Addr, error)
|
||||
b []byte
|
||||
as []Addr
|
||||
}
|
||||
|
||||
var parseAddrsLittleEndianTests = []parseAddrsTest{
|
||||
{
|
||||
syscall.RTA_DST | syscall.RTA_GATEWAY | syscall.RTA_NETMASK | syscall.RTA_BRD,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x38, 0x12, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x38, 0x12, 0x2, 0x0, 0x6, 0x3, 0x6, 0x0,
|
||||
0x65, 0x6d, 0x31, 0x0, 0xc, 0x29, 0x66, 0x2c,
|
||||
0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x10, 0x2, 0x0, 0x0, 0xac, 0x10, 0xdc, 0xb4,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x10, 0x2, 0x0, 0x0, 0xac, 0x10, 0xdc, 0xff,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
},
|
||||
[]Addr{
|
||||
&LinkAddr{Index: 0},
|
||||
&LinkAddr{Index: 2, Name: "em1", Addr: []byte{0x00, 0x0c, 0x29, 0x66, 0x2c, 0xdc}},
|
||||
&Inet4Addr{IP: [4]byte{172, 16, 220, 180}},
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
nil,
|
||||
&Inet4Addr{IP: [4]byte{172, 16, 220, 255}},
|
||||
},
|
||||
},
|
||||
{
|
||||
syscall.RTA_NETMASK | syscall.RTA_IFP | syscall.RTA_IFA,
|
||||
parseKernelInetAddr,
|
||||
[]byte{
|
||||
0x7, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0x0,
|
||||
|
||||
0x18, 0x12, 0xa, 0x0, 0x87, 0x8, 0x0, 0x0,
|
||||
0x76, 0x6c, 0x61, 0x6e, 0x35, 0x36, 0x38, 0x32,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
|
||||
0x10, 0x2, 0x0, 0x0, 0xa9, 0xfe, 0x0, 0x1,
|
||||
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||
},
|
||||
[]Addr{
|
||||
nil,
|
||||
nil,
|
||||
&Inet4Addr{IP: [4]byte{255, 255, 255, 0}},
|
||||
nil,
|
||||
&LinkAddr{Index: 10, Name: "vlan5682"},
|
||||
&Inet4Addr{IP: [4]byte{169, 254, 0, 1}},
|
||||
nil,
|
||||
nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestParseAddrs(t *testing.T) {
|
||||
tests := parseAddrsLittleEndianTests
|
||||
if nativeEndian != littleEndian {
|
||||
t.Skip("no test for non-little endian machine yet")
|
||||
}
|
||||
|
||||
for i, tt := range tests {
|
||||
as, err := parseAddrs(tt.attrs, tt.fn, tt.b)
|
||||
if err != nil {
|
||||
t.Error(i, err)
|
||||
continue
|
||||
}
|
||||
as = as[:8] // the list varies between operating systems
|
||||
if !reflect.DeepEqual(as, tt.as) {
|
||||
t.Errorf("#%d: got %+v; want %+v", i, as, tt.as)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
// This file contains duplicates of encoding/binary package.
|
||||
//
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
// An InterfaceMessage represents an interface message.
|
||||
type InterfaceMessage struct {
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build dragonfly || freebsd || netbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
func (w *wireFormat) parseInterfaceAnnounceMessage(_ RIBType, b []byte) (Message, error) {
|
||||
if len(b) < w.bodyOff {
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || netbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import "syscall"
|
||||
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
func (w *wireFormat) parseInterfaceMulticastAddrMessage(_ RIBType, b []byte) (Message, error) {
|
||||
if len(b) < w.bodyOff {
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import "syscall"
|
||||
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
// A Message represents a routing message.
|
||||
type Message interface {
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// 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.
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFetchAndParseRIBOnDarwin(t *testing.T) {
|
||||
for _, typ := range []RIBType{syscall.NET_RT_FLAGS, syscall.NET_RT_DUMP2, syscall.NET_RT_IFLIST2} {
|
||||
var lastErr error
|
||||
var ms []Message
|
||||
for _, af := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
|
||||
rs, err := fetchAndParseRIB(af, typ)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
ms = append(ms, rs...)
|
||||
}
|
||||
if len(ms) == 0 && lastErr != nil {
|
||||
t.Error(typ, lastErr)
|
||||
continue
|
||||
}
|
||||
ss, err := msgs(ms).validate()
|
||||
if err != nil {
|
||||
t.Error(typ, err)
|
||||
continue
|
||||
}
|
||||
for _, s := range ss {
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
// 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.
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFetchAndParseRIBOnFreeBSD(t *testing.T) {
|
||||
for _, typ := range []RIBType{syscall.NET_RT_IFMALIST} {
|
||||
var lastErr error
|
||||
var ms []Message
|
||||
for _, af := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
|
||||
rs, err := fetchAndParseRIB(af, typ)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
ms = append(ms, rs...)
|
||||
}
|
||||
if len(ms) == 0 && lastErr != nil {
|
||||
t.Error(typ, lastErr)
|
||||
continue
|
||||
}
|
||||
ss, err := msgs(ms).validate()
|
||||
if err != nil {
|
||||
t.Error(typ, err)
|
||||
continue
|
||||
}
|
||||
for _, s := range ss {
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchAndParseRIBOnFreeBSD10AndAbove(t *testing.T) {
|
||||
if _, err := FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLISTL, 0); err != nil {
|
||||
t.Skip("NET_RT_IFLISTL not supported")
|
||||
}
|
||||
if compatFreeBSD32 {
|
||||
t.Skip("NET_RT_IFLIST vs. NET_RT_IFLISTL doesn't work for 386 emulation on amd64")
|
||||
}
|
||||
|
||||
var tests = [2]struct {
|
||||
typ RIBType
|
||||
b []byte
|
||||
msgs []Message
|
||||
ss []string
|
||||
}{
|
||||
{typ: syscall.NET_RT_IFLIST},
|
||||
{typ: syscall.NET_RT_IFLISTL},
|
||||
}
|
||||
for i := range tests {
|
||||
var lastErr error
|
||||
for _, af := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
|
||||
rs, err := fetchAndParseRIB(af, tests[i].typ)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
tests[i].msgs = append(tests[i].msgs, rs...)
|
||||
}
|
||||
if len(tests[i].msgs) == 0 && lastErr != nil {
|
||||
t.Error(tests[i].typ, lastErr)
|
||||
continue
|
||||
}
|
||||
tests[i].ss, lastErr = msgs(tests[i].msgs).validate()
|
||||
if lastErr != nil {
|
||||
t.Error(tests[i].typ, lastErr)
|
||||
continue
|
||||
}
|
||||
for _, s := range tests[i].ss {
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
for i := len(tests) - 1; i > 0; i-- {
|
||||
if len(tests[i].ss) != len(tests[i-1].ss) {
|
||||
t.Errorf("got %v; want %v", tests[i].ss, tests[i-1].ss)
|
||||
continue
|
||||
}
|
||||
for j, s1 := range tests[i].ss {
|
||||
s0 := tests[i-1].ss[j]
|
||||
if s1 != s0 {
|
||||
t.Errorf("got %s; want %s", s1, s0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
// 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.
|
||||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestFetchAndParseRIB(t *testing.T) {
|
||||
for _, typ := range []RIBType{syscall.NET_RT_DUMP, syscall.NET_RT_IFLIST} {
|
||||
var lastErr error
|
||||
var ms []Message
|
||||
for _, af := range []int{syscall.AF_UNSPEC, syscall.AF_INET, syscall.AF_INET6} {
|
||||
rs, err := fetchAndParseRIB(af, typ)
|
||||
if err != nil {
|
||||
lastErr = err
|
||||
continue
|
||||
}
|
||||
ms = append(ms, rs...)
|
||||
}
|
||||
if len(ms) == 0 && lastErr != nil {
|
||||
t.Error(typ, lastErr)
|
||||
continue
|
||||
}
|
||||
ss, err := msgs(ms).validate()
|
||||
if err != nil {
|
||||
t.Error(typ, err)
|
||||
continue
|
||||
}
|
||||
for _, s := range ss {
|
||||
t.Log(typ, s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
rtmonSock int
|
||||
rtmonErr error
|
||||
)
|
||||
|
||||
func init() {
|
||||
// We need to keep rtmonSock alive to avoid treading on
|
||||
// recycled socket descriptors.
|
||||
rtmonSock, rtmonErr = syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
|
||||
}
|
||||
|
||||
// TestMonitorAndParseRIB leaks a worker goroutine and a socket
|
||||
// descriptor but that's intentional.
|
||||
func TestMonitorAndParseRIB(t *testing.T) {
|
||||
if testing.Short() || os.Getuid() != 0 {
|
||||
t.Skip("must be root")
|
||||
}
|
||||
|
||||
if rtmonErr != nil {
|
||||
t.Fatal(rtmonErr)
|
||||
}
|
||||
|
||||
// We suppose that using an IPv4 link-local address and the
|
||||
// dot1Q ID for Token Ring and FDDI doesn't harm anyone.
|
||||
pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
|
||||
if err := pv.configure(1002); err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
if err := pv.setup(); err != nil {
|
||||
t.Skip(err)
|
||||
}
|
||||
pv.teardown()
|
||||
|
||||
go func() {
|
||||
b := make([]byte, os.Getpagesize())
|
||||
for {
|
||||
// There's no easy way to unblock this read
|
||||
// call because the routing message exchange
|
||||
// over routing socket is a connectionless
|
||||
// message-oriented protocol, no control plane
|
||||
// for signaling connectivity, and we cannot
|
||||
// use the net package of standard library due
|
||||
// to the lack of support for routing socket
|
||||
// and circular dependency.
|
||||
n, err := syscall.Read(rtmonSock, b)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
ms, err := ParseRIB(0, b[:n])
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
ss, err := msgs(ms).validate()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
for _, s := range ss {
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
for _, vid := range []int{1002, 1003, 1004, 1005} {
|
||||
pv := &propVirtual{addr: "169.254.0.1", mask: "255.255.255.0"}
|
||||
if err := pv.configure(vid); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := pv.setup(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
if err := pv.teardown(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseRIBWithFuzz(t *testing.T) {
|
||||
for _, fuzz := range []string{
|
||||
"0\x00\x05\x050000000000000000" +
|
||||
"00000000000000000000" +
|
||||
"00000000000000000000" +
|
||||
"00000000000000000000" +
|
||||
"0000000000000\x02000000" +
|
||||
"00000000",
|
||||
"\x02\x00\x05\f0000000000000000" +
|
||||
"0\x0200000000000000",
|
||||
"\x02\x00\x05\x100000000000000\x1200" +
|
||||
"0\x00\xff\x00",
|
||||
"\x02\x00\x05\f0000000000000000" +
|
||||
"0\x12000\x00\x02\x0000",
|
||||
"\x00\x00\x00\x01\x00",
|
||||
"00000",
|
||||
} {
|
||||
for typ := RIBType(0); typ < 256; typ++ {
|
||||
ParseRIB(typ, []byte(fuzz))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRouteMessage(t *testing.T) {
|
||||
s, err := syscall.Socket(syscall.AF_ROUTE, syscall.SOCK_RAW, syscall.AF_UNSPEC)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer syscall.Close(s)
|
||||
|
||||
var ms []RouteMessage
|
||||
for _, af := range []int{syscall.AF_INET, syscall.AF_INET6} {
|
||||
if _, err := fetchAndParseRIB(af, syscall.NET_RT_DUMP); err != nil {
|
||||
t.Log(err)
|
||||
continue
|
||||
}
|
||||
switch af {
|
||||
case syscall.AF_INET:
|
||||
ms = append(ms, []RouteMessage{
|
||||
{
|
||||
Type: syscall.RTM_GET,
|
||||
Addrs: []Addr{
|
||||
syscall.RTAX_DST: &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
|
||||
syscall.RTAX_GATEWAY: nil,
|
||||
syscall.RTAX_NETMASK: nil,
|
||||
syscall.RTAX_GENMASK: nil,
|
||||
syscall.RTAX_IFP: &LinkAddr{},
|
||||
syscall.RTAX_IFA: &Inet4Addr{},
|
||||
syscall.RTAX_AUTHOR: nil,
|
||||
syscall.RTAX_BRD: &Inet4Addr{},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: syscall.RTM_GET,
|
||||
Addrs: []Addr{
|
||||
syscall.RTAX_DST: &Inet4Addr{IP: [4]byte{127, 0, 0, 1}},
|
||||
},
|
||||
},
|
||||
}...)
|
||||
case syscall.AF_INET6:
|
||||
ms = append(ms, []RouteMessage{
|
||||
{
|
||||
Type: syscall.RTM_GET,
|
||||
Addrs: []Addr{
|
||||
syscall.RTAX_DST: &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
|
||||
syscall.RTAX_GATEWAY: nil,
|
||||
syscall.RTAX_NETMASK: nil,
|
||||
syscall.RTAX_GENMASK: nil,
|
||||
syscall.RTAX_IFP: &LinkAddr{},
|
||||
syscall.RTAX_IFA: &Inet6Addr{},
|
||||
syscall.RTAX_AUTHOR: nil,
|
||||
syscall.RTAX_BRD: &Inet6Addr{},
|
||||
},
|
||||
},
|
||||
{
|
||||
Type: syscall.RTM_GET,
|
||||
Addrs: []Addr{
|
||||
syscall.RTAX_DST: &Inet6Addr{IP: [16]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}},
|
||||
},
|
||||
},
|
||||
}...)
|
||||
}
|
||||
}
|
||||
for i, m := range ms {
|
||||
m.ID = uintptr(os.Getpid())
|
||||
m.Seq = i + 1
|
||||
wb, err := m.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("%v: %v", m, err)
|
||||
}
|
||||
if _, err := syscall.Write(s, wb); err != nil {
|
||||
t.Fatalf("%v: %v", m, err)
|
||||
}
|
||||
rb := make([]byte, os.Getpagesize())
|
||||
n, err := syscall.Read(s, rb)
|
||||
if err != nil {
|
||||
t.Fatalf("%v: %v", m, err)
|
||||
}
|
||||
rms, err := ParseRIB(0, rb[:n])
|
||||
if err != nil {
|
||||
t.Fatalf("%v: %v", m, err)
|
||||
}
|
||||
for _, rm := range rms {
|
||||
if rm, ok := rm.(*RouteMessage); ok && rm.Err != nil {
|
||||
t.Errorf("%v: %v", m, rm.Err)
|
||||
}
|
||||
}
|
||||
ss, err := msgs(rms).validate()
|
||||
if err != nil {
|
||||
t.Fatalf("%v: %v", m, err)
|
||||
}
|
||||
for _, s := range ss {
|
||||
t.Log(s)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
// 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
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
|
@ -0,0 +1,382 @@
|
|||
// 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.
|
||||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func (m *RouteMessage) String() string {
|
||||
return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[12:16])))
|
||||
}
|
||||
|
||||
func (m *InterfaceMessage) String() string {
|
||||
var attrs addrAttrs
|
||||
if runtime.GOOS == "openbsd" {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
|
||||
} else {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
|
||||
}
|
||||
return fmt.Sprintf("%s", attrs)
|
||||
}
|
||||
|
||||
func (m *InterfaceAddrMessage) String() string {
|
||||
var attrs addrAttrs
|
||||
if runtime.GOOS == "openbsd" {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
|
||||
} else {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
|
||||
}
|
||||
return fmt.Sprintf("%s", attrs)
|
||||
}
|
||||
|
||||
func (m *InterfaceMulticastAddrMessage) String() string {
|
||||
return fmt.Sprintf("%s", addrAttrs(nativeEndian.Uint32(m.raw[4:8])))
|
||||
}
|
||||
|
||||
func (m *InterfaceAnnounceMessage) String() string {
|
||||
what := "<nil>"
|
||||
switch m.What {
|
||||
case 0:
|
||||
what = "arrival"
|
||||
case 1:
|
||||
what = "departure"
|
||||
}
|
||||
return fmt.Sprintf("(%d %s %s)", m.Index, m.Name, what)
|
||||
}
|
||||
|
||||
func (m *InterfaceMetrics) String() string {
|
||||
return fmt.Sprintf("(type=%d mtu=%d)", m.Type, m.MTU)
|
||||
}
|
||||
|
||||
func (m *RouteMetrics) String() string {
|
||||
return fmt.Sprintf("(pmtu=%d)", m.PathMTU)
|
||||
}
|
||||
|
||||
type addrAttrs uint
|
||||
|
||||
var addrAttrNames = [...]string{
|
||||
"dst",
|
||||
"gateway",
|
||||
"netmask",
|
||||
"genmask",
|
||||
"ifp",
|
||||
"ifa",
|
||||
"author",
|
||||
"brd",
|
||||
"df:mpls1-n:tag-o:src", // mpls1 for dragonfly, tag for netbsd, src for openbsd
|
||||
"df:mpls2-o:srcmask", // mpls2 for dragonfly, srcmask for openbsd
|
||||
"df:mpls3-o:label", // mpls3 for dragonfly, label for openbsd
|
||||
"o:bfd", // bfd for openbsd
|
||||
"o:dns", // dns for openbsd
|
||||
"o:static", // static for openbsd
|
||||
"o:search", // search for openbsd
|
||||
}
|
||||
|
||||
func (attrs addrAttrs) String() string {
|
||||
var s string
|
||||
for i, name := range addrAttrNames {
|
||||
if attrs&(1<<uint(i)) != 0 {
|
||||
if s != "" {
|
||||
s += "|"
|
||||
}
|
||||
s += name
|
||||
}
|
||||
}
|
||||
if s == "" {
|
||||
return "<nil>"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type msgs []Message
|
||||
|
||||
func (ms msgs) validate() ([]string, error) {
|
||||
var ss []string
|
||||
for _, m := range ms {
|
||||
switch m := m.(type) {
|
||||
case *RouteMessage:
|
||||
if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[12:16]))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sys := m.Sys()
|
||||
if sys == nil {
|
||||
return nil, fmt.Errorf("no sys for %s", m.String())
|
||||
}
|
||||
ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
|
||||
case *InterfaceMessage:
|
||||
var attrs addrAttrs
|
||||
if runtime.GOOS == "openbsd" {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
|
||||
} else {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
|
||||
}
|
||||
if err := addrs(m.Addrs).match(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sys := m.Sys()
|
||||
if sys == nil {
|
||||
return nil, fmt.Errorf("no sys for %s", m.String())
|
||||
}
|
||||
ss = append(ss, m.String()+" "+syss(sys).String()+" "+addrs(m.Addrs).String())
|
||||
case *InterfaceAddrMessage:
|
||||
var attrs addrAttrs
|
||||
if runtime.GOOS == "openbsd" {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[12:16]))
|
||||
} else {
|
||||
attrs = addrAttrs(nativeEndian.Uint32(m.raw[4:8]))
|
||||
}
|
||||
if err := addrs(m.Addrs).match(attrs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
|
||||
case *InterfaceMulticastAddrMessage:
|
||||
if err := addrs(m.Addrs).match(addrAttrs(nativeEndian.Uint32(m.raw[4:8]))); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ss = append(ss, m.String()+" "+addrs(m.Addrs).String())
|
||||
case *InterfaceAnnounceMessage:
|
||||
ss = append(ss, m.String())
|
||||
default:
|
||||
ss = append(ss, fmt.Sprintf("%+v", m))
|
||||
}
|
||||
}
|
||||
return ss, nil
|
||||
}
|
||||
|
||||
type syss []Sys
|
||||
|
||||
func (sys syss) String() string {
|
||||
var s string
|
||||
for _, sy := range sys {
|
||||
switch sy := sy.(type) {
|
||||
case *InterfaceMetrics:
|
||||
if len(s) > 0 {
|
||||
s += " "
|
||||
}
|
||||
s += sy.String()
|
||||
case *RouteMetrics:
|
||||
if len(s) > 0 {
|
||||
s += " "
|
||||
}
|
||||
s += sy.String()
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
type addrFamily int
|
||||
|
||||
func (af addrFamily) String() string {
|
||||
switch af {
|
||||
case syscall.AF_UNSPEC:
|
||||
return "unspec"
|
||||
case syscall.AF_LINK:
|
||||
return "link"
|
||||
case syscall.AF_INET:
|
||||
return "inet4"
|
||||
case syscall.AF_INET6:
|
||||
return "inet6"
|
||||
default:
|
||||
return fmt.Sprintf("%d", af)
|
||||
}
|
||||
}
|
||||
|
||||
const hexDigit = "0123456789abcdef"
|
||||
|
||||
type llAddr []byte
|
||||
|
||||
func (a llAddr) String() string {
|
||||
if len(a) == 0 {
|
||||
return ""
|
||||
}
|
||||
buf := make([]byte, 0, len(a)*3-1)
|
||||
for i, b := range a {
|
||||
if i > 0 {
|
||||
buf = append(buf, ':')
|
||||
}
|
||||
buf = append(buf, hexDigit[b>>4])
|
||||
buf = append(buf, hexDigit[b&0xF])
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
type ipAddr []byte
|
||||
|
||||
func (a ipAddr) String() string {
|
||||
if len(a) == 0 {
|
||||
return "<nil>"
|
||||
}
|
||||
if len(a) == 4 {
|
||||
return fmt.Sprintf("%d.%d.%d.%d", a[0], a[1], a[2], a[3])
|
||||
}
|
||||
if len(a) == 16 {
|
||||
return fmt.Sprintf("%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15])
|
||||
}
|
||||
s := make([]byte, len(a)*2)
|
||||
for i, tn := range a {
|
||||
s[i*2], s[i*2+1] = hexDigit[tn>>4], hexDigit[tn&0xf]
|
||||
}
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func (a *LinkAddr) String() string {
|
||||
name := a.Name
|
||||
if name == "" {
|
||||
name = "<nil>"
|
||||
}
|
||||
lla := llAddr(a.Addr).String()
|
||||
if lla == "" {
|
||||
lla = "<nil>"
|
||||
}
|
||||
return fmt.Sprintf("(%v %d %s %s)", addrFamily(a.Family()), a.Index, name, lla)
|
||||
}
|
||||
|
||||
func (a *Inet4Addr) String() string {
|
||||
return fmt.Sprintf("(%v %v)", addrFamily(a.Family()), ipAddr(a.IP[:]))
|
||||
}
|
||||
|
||||
func (a *Inet6Addr) String() string {
|
||||
return fmt.Sprintf("(%v %v %d)", addrFamily(a.Family()), ipAddr(a.IP[:]), a.ZoneID)
|
||||
}
|
||||
|
||||
func (a *DefaultAddr) String() string {
|
||||
return fmt.Sprintf("(%v %s)", addrFamily(a.Family()), ipAddr(a.Raw[2:]).String())
|
||||
}
|
||||
|
||||
type addrs []Addr
|
||||
|
||||
func (as addrs) String() string {
|
||||
var s string
|
||||
for _, a := range as {
|
||||
if a == nil {
|
||||
continue
|
||||
}
|
||||
if len(s) > 0 {
|
||||
s += " "
|
||||
}
|
||||
switch a := a.(type) {
|
||||
case *LinkAddr:
|
||||
s += a.String()
|
||||
case *Inet4Addr:
|
||||
s += a.String()
|
||||
case *Inet6Addr:
|
||||
s += a.String()
|
||||
case *DefaultAddr:
|
||||
s += a.String()
|
||||
}
|
||||
}
|
||||
if s == "" {
|
||||
return "<nil>"
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func (as addrs) match(attrs addrAttrs) error {
|
||||
var ts addrAttrs
|
||||
af := syscall.AF_UNSPEC
|
||||
for i := range as {
|
||||
if as[i] != nil {
|
||||
ts |= 1 << uint(i)
|
||||
}
|
||||
switch as[i].(type) {
|
||||
case *Inet4Addr:
|
||||
if af == syscall.AF_UNSPEC {
|
||||
af = syscall.AF_INET
|
||||
}
|
||||
if af != syscall.AF_INET {
|
||||
return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
|
||||
}
|
||||
case *Inet6Addr:
|
||||
if af == syscall.AF_UNSPEC {
|
||||
af = syscall.AF_INET6
|
||||
}
|
||||
if af != syscall.AF_INET6 {
|
||||
return fmt.Errorf("got %v; want %v", addrs(as), addrFamily(af))
|
||||
}
|
||||
}
|
||||
}
|
||||
if ts != attrs && ts > attrs {
|
||||
return fmt.Errorf("%v not included in %v", ts, attrs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func fetchAndParseRIB(af int, typ RIBType) ([]Message, error) {
|
||||
b, err := FetchRIB(af, typ, 0)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
|
||||
}
|
||||
ms, err := ParseRIB(typ, b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%v %d %v", addrFamily(af), typ, err)
|
||||
}
|
||||
return ms, nil
|
||||
}
|
||||
|
||||
// propVirtual is a proprietary virtual network interface.
|
||||
type propVirtual struct {
|
||||
name string
|
||||
addr, mask string
|
||||
setupCmds []*exec.Cmd
|
||||
teardownCmds []*exec.Cmd
|
||||
}
|
||||
|
||||
func (pv *propVirtual) setup() error {
|
||||
for _, cmd := range pv.setupCmds {
|
||||
if err := cmd.Run(); err != nil {
|
||||
pv.teardown()
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pv *propVirtual) teardown() error {
|
||||
for _, cmd := range pv.teardownCmds {
|
||||
if err := cmd.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pv *propVirtual) configure(suffix int) error {
|
||||
if runtime.GOOS == "openbsd" {
|
||||
pv.name = fmt.Sprintf("vether%d", suffix)
|
||||
} else {
|
||||
pv.name = fmt.Sprintf("vlan%d", suffix)
|
||||
}
|
||||
xname, err := exec.LookPath("ifconfig")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
|
||||
Path: xname,
|
||||
Args: []string{"ifconfig", pv.name, "create"},
|
||||
})
|
||||
if runtime.GOOS == "netbsd" {
|
||||
// NetBSD requires an underlying dot1Q-capable network
|
||||
// interface.
|
||||
pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
|
||||
Path: xname,
|
||||
Args: []string{"ifconfig", pv.name, "vlan", fmt.Sprintf("%d", suffix&0xfff), "vlanif", "wm0"},
|
||||
})
|
||||
}
|
||||
pv.setupCmds = append(pv.setupCmds, &exec.Cmd{
|
||||
Path: xname,
|
||||
Args: []string{"ifconfig", pv.name, "inet", pv.addr, "netmask", pv.mask},
|
||||
})
|
||||
pv.teardownCmds = append(pv.teardownCmds, &exec.Cmd{
|
||||
Path: xname,
|
||||
Args: []string{"ifconfig", pv.name, "destroy"},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import "syscall"
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import "syscall"
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
//go:build darwin || dragonfly || freebsd || netbsd || openbsd
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
import _ "unsafe" // for linkname
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_darwin.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrDarwin15 = 0x70
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_dragonfly.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrDragonFlyBSD4 = 0xb0
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrlFreeBSD10 = 0x68
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrlFreeBSD10 = 0xb0
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrlFreeBSD10 = 0x68
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrlFreeBSD10 = 0xb0
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_freebsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrlFreeBSD10 = 0xb0
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_netbsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofIfMsghdrNetBSD7 = 0x98
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
// Code generated by cmd/cgo -godefs; DO NOT EDIT.
|
||||
// cgo -godefs defs_openbsd.go
|
||||
|
||||
package route
|
||||
package routebsd
|
||||
|
||||
const (
|
||||
sizeofRtMsghdr = 0x60
|
||||
|
|
@ -7,9 +7,8 @@
|
|||
package net
|
||||
|
||||
import (
|
||||
"internal/routebsd"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
)
|
||||
|
||||
// If the ifindex is zero, interfaceTable returns mappings of all
|
||||
|
|
@ -28,19 +27,19 @@ func interfaceTable(ifindex int) ([]Interface, error) {
|
|||
n = 0
|
||||
for _, m := range msgs {
|
||||
switch m := m.(type) {
|
||||
case *route.InterfaceMessage:
|
||||
case *routebsd.InterfaceMessage:
|
||||
if ifindex != 0 && ifindex != m.Index {
|
||||
continue
|
||||
}
|
||||
ift[n].Index = m.Index
|
||||
ift[n].Name = m.Name
|
||||
ift[n].Flags = linkFlags(m.Flags)
|
||||
if sa, ok := m.Addrs[syscall.RTAX_IFP].(*route.LinkAddr); ok && len(sa.Addr) > 0 {
|
||||
if sa, ok := m.Addrs[syscall.RTAX_IFP].(*routebsd.LinkAddr); ok && len(sa.Addr) > 0 {
|
||||
ift[n].HardwareAddr = make([]byte, len(sa.Addr))
|
||||
copy(ift[n].HardwareAddr, sa.Addr)
|
||||
}
|
||||
for _, sys := range m.Sys() {
|
||||
if imx, ok := sys.(*route.InterfaceMetrics); ok {
|
||||
if imx, ok := sys.(*routebsd.InterfaceMetrics); ok {
|
||||
ift[n].MTU = imx.MTU
|
||||
break
|
||||
}
|
||||
|
|
@ -92,27 +91,27 @@ func interfaceAddrTable(ifi *Interface) ([]Addr, error) {
|
|||
ifat := make([]Addr, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
switch m := m.(type) {
|
||||
case *route.InterfaceAddrMessage:
|
||||
case *routebsd.InterfaceAddrMessage:
|
||||
if index != 0 && index != m.Index {
|
||||
continue
|
||||
}
|
||||
var mask IPMask
|
||||
switch sa := m.Addrs[syscall.RTAX_NETMASK].(type) {
|
||||
case *route.Inet4Addr:
|
||||
case *routebsd.Inet4Addr:
|
||||
mask = IPv4Mask(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
|
||||
case *route.Inet6Addr:
|
||||
case *routebsd.Inet6Addr:
|
||||
mask = make(IPMask, IPv6len)
|
||||
copy(mask, sa.IP[:])
|
||||
}
|
||||
var ip IP
|
||||
switch sa := m.Addrs[syscall.RTAX_IFA].(type) {
|
||||
case *route.Inet4Addr:
|
||||
case *routebsd.Inet4Addr:
|
||||
ip = IPv4(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
|
||||
case *route.Inet6Addr:
|
||||
case *routebsd.Inet6Addr:
|
||||
ip = make(IP, IPv6len)
|
||||
copy(ip, sa.IP[:])
|
||||
}
|
||||
if ip != nil && mask != nil { // NetBSD may contain route.LinkAddr
|
||||
if ip != nil && mask != nil { // NetBSD may contain routebsd.LinkAddr
|
||||
ifat = append(ifat, &IPNet{IP: ip, Mask: mask})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,17 +7,16 @@
|
|||
package net
|
||||
|
||||
import (
|
||||
"internal/routebsd"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
)
|
||||
|
||||
func interfaceMessages(ifindex int) ([]route.Message, error) {
|
||||
rib, err := route.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST, ifindex)
|
||||
func interfaceMessages(ifindex int) ([]routebsd.Message, error) {
|
||||
rib, err := routebsd.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST, ifindex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return route.ParseRIB(syscall.NET_RT_IFLIST, rib)
|
||||
return routebsd.ParseRIB(syscall.NET_RT_IFLIST, rib)
|
||||
}
|
||||
|
||||
// interfaceMulticastAddrTable returns addresses for a specific
|
||||
|
|
|
|||
|
|
@ -5,42 +5,41 @@
|
|||
package net
|
||||
|
||||
import (
|
||||
"internal/routebsd"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
)
|
||||
|
||||
func interfaceMessages(ifindex int) ([]route.Message, error) {
|
||||
rib, err := route.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST, ifindex)
|
||||
func interfaceMessages(ifindex int) ([]routebsd.Message, error) {
|
||||
rib, err := routebsd.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST, ifindex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return route.ParseRIB(syscall.NET_RT_IFLIST, rib)
|
||||
return routebsd.ParseRIB(syscall.NET_RT_IFLIST, rib)
|
||||
}
|
||||
|
||||
// interfaceMulticastAddrTable returns addresses for a specific
|
||||
// interface.
|
||||
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
|
||||
rib, err := route.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST2, ifi.Index)
|
||||
rib, err := routebsd.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFLIST2, ifi.Index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgs, err := route.ParseRIB(syscall.NET_RT_IFLIST2, rib)
|
||||
msgs, err := routebsd.ParseRIB(syscall.NET_RT_IFLIST2, rib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifmat := make([]Addr, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
switch m := m.(type) {
|
||||
case *route.InterfaceMulticastAddrMessage:
|
||||
case *routebsd.InterfaceMulticastAddrMessage:
|
||||
if ifi.Index != m.Index {
|
||||
continue
|
||||
}
|
||||
var ip IP
|
||||
switch sa := m.Addrs[syscall.RTAX_IFA].(type) {
|
||||
case *route.Inet4Addr:
|
||||
case *routebsd.Inet4Addr:
|
||||
ip = IPv4(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
|
||||
case *route.Inet6Addr:
|
||||
case *routebsd.Inet6Addr:
|
||||
ip = make(IP, IPv6len)
|
||||
copy(ip, sa.IP[:])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,42 +5,41 @@
|
|||
package net
|
||||
|
||||
import (
|
||||
"internal/routebsd"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/net/route"
|
||||
)
|
||||
|
||||
func interfaceMessages(ifindex int) ([]route.Message, error) {
|
||||
rib, err := route.FetchRIB(syscall.AF_UNSPEC, route.RIBTypeInterface, ifindex)
|
||||
func interfaceMessages(ifindex int) ([]routebsd.Message, error) {
|
||||
rib, err := routebsd.FetchRIB(syscall.AF_UNSPEC, routebsd.RIBTypeInterface, ifindex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return route.ParseRIB(route.RIBTypeInterface, rib)
|
||||
return routebsd.ParseRIB(routebsd.RIBTypeInterface, rib)
|
||||
}
|
||||
|
||||
// interfaceMulticastAddrTable returns addresses for a specific
|
||||
// interface.
|
||||
func interfaceMulticastAddrTable(ifi *Interface) ([]Addr, error) {
|
||||
rib, err := route.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFMALIST, ifi.Index)
|
||||
rib, err := routebsd.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_IFMALIST, ifi.Index)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
msgs, err := route.ParseRIB(syscall.NET_RT_IFMALIST, rib)
|
||||
msgs, err := routebsd.ParseRIB(syscall.NET_RT_IFMALIST, rib)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ifmat := make([]Addr, 0, len(msgs))
|
||||
for _, m := range msgs {
|
||||
switch m := m.(type) {
|
||||
case *route.InterfaceMulticastAddrMessage:
|
||||
case *routebsd.InterfaceMulticastAddrMessage:
|
||||
if ifi.Index != m.Index {
|
||||
continue
|
||||
}
|
||||
var ip IP
|
||||
switch sa := m.Addrs[syscall.RTAX_IFA].(type) {
|
||||
case *route.Inet4Addr:
|
||||
case *routebsd.Inet4Addr:
|
||||
ip = IPv4(sa.IP[0], sa.IP[1], sa.IP[2], sa.IP[3])
|
||||
case *route.Inet6Addr:
|
||||
case *routebsd.Inet6Addr:
|
||||
ip = make(IP, IPv6len)
|
||||
copy(ip, sa.IP[:])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ golang.org/x/net/http2/hpack
|
|||
golang.org/x/net/idna
|
||||
golang.org/x/net/lif
|
||||
golang.org/x/net/nettest
|
||||
golang.org/x/net/route
|
||||
# golang.org/x/sys v0.28.0
|
||||
## explicit; go 1.18
|
||||
golang.org/x/sys/cpu
|
||||
|
|
|
|||
Loading…
Reference in New Issue