2016-03-01 15:57:46 -07:00
|
|
|
// Copyright 2013 The Go Authors. All rights reserved.
|
2013-02-27 22:58:41 -07:00
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
2013-08-23 10:18:22 -06:00
|
|
|
// +build darwin dragonfly freebsd linux netbsd openbsd
|
2013-02-27 22:58:41 -07:00
|
|
|
|
|
|
|
package net
|
|
|
|
|
|
|
|
import (
|
2016-05-12 14:02:00 -06:00
|
|
|
"fmt"
|
2013-02-27 22:58:41 -07:00
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"runtime"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
type testInterface struct {
|
|
|
|
name string
|
|
|
|
local string
|
|
|
|
remote string
|
|
|
|
setupCmds []*exec.Cmd
|
|
|
|
teardownCmds []*exec.Cmd
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ti *testInterface) setup() error {
|
|
|
|
for _, cmd := range ti.setupCmds {
|
2016-05-12 14:02:00 -06:00
|
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
|
|
return fmt.Errorf("args=%v out=%q err=%v", cmd.Args, string(out), err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ti *testInterface) teardown() error {
|
|
|
|
for _, cmd := range ti.teardownCmds {
|
2016-05-12 14:02:00 -06:00
|
|
|
if out, err := cmd.CombinedOutput(); err != nil {
|
|
|
|
return fmt.Errorf("args=%v out=%q err=%v ", cmd.Args, string(out), err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestPointToPointInterface(t *testing.T) {
|
2013-03-24 22:25:28 -06:00
|
|
|
if testing.Short() {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Skip("avoid external network")
|
2013-03-24 22:25:28 -06:00
|
|
|
}
|
2015-04-30 21:38:42 -06:00
|
|
|
if runtime.GOOS == "darwin" {
|
|
|
|
t.Skipf("not supported on %s", runtime.GOOS)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
if os.Getuid() != 0 {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Skip("must be root")
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
|
2016-05-12 14:02:00 -06:00
|
|
|
// We suppose that using IPv4 link-local addresses doesn't
|
|
|
|
// harm anyone.
|
2013-02-27 22:58:41 -07:00
|
|
|
local, remote := "169.254.0.1", "169.254.0.254"
|
|
|
|
ip := ParseIP(remote)
|
|
|
|
for i := 0; i < 3; i++ {
|
2015-06-23 06:40:33 -06:00
|
|
|
ti := &testInterface{local: local, remote: remote}
|
|
|
|
if err := ti.setPointToPoint(5963 + i); err != nil {
|
2016-02-24 03:55:20 -07:00
|
|
|
t.Skipf("test requires external command: %v", err)
|
2013-03-01 18:56:51 -07:00
|
|
|
}
|
2013-02-27 22:58:41 -07:00
|
|
|
if err := ti.setup(); err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
} else {
|
|
|
|
time.Sleep(3 * time.Millisecond)
|
|
|
|
}
|
|
|
|
ift, err := Interfaces()
|
|
|
|
if err != nil {
|
|
|
|
ti.teardown()
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
for _, ifi := range ift {
|
2015-06-23 06:40:33 -06:00
|
|
|
if ti.name != ifi.Name {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
ifat, err := ifi.Addrs()
|
|
|
|
if err != nil {
|
|
|
|
ti.teardown()
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
for _, ifa := range ifat {
|
|
|
|
if ip.Equal(ifa.(*IPNet).IP) {
|
2013-02-27 22:58:41 -07:00
|
|
|
ti.teardown()
|
2015-06-23 06:40:33 -06:00
|
|
|
t.Fatalf("got %v", ifa)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if err := ti.teardown(); err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
} else {
|
|
|
|
time.Sleep(3 * time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestInterfaceArrivalAndDeparture(t *testing.T) {
|
2013-03-24 22:25:28 -06:00
|
|
|
if testing.Short() {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Skip("avoid external network")
|
2013-03-24 22:25:28 -06:00
|
|
|
}
|
2013-02-27 22:58:41 -07:00
|
|
|
if os.Getuid() != 0 {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Skip("must be root")
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
|
2016-05-12 14:02:00 -06:00
|
|
|
// We suppose that using IPv4 link-local addresses and the
|
|
|
|
// dot1Q ID for Token Ring and FDDI doesn't harm anyone.
|
2015-06-23 06:40:33 -06:00
|
|
|
local, remote := "169.254.0.1", "169.254.0.254"
|
|
|
|
ip := ParseIP(remote)
|
2016-05-12 14:02:00 -06:00
|
|
|
for _, vid := range []int{1002, 1003, 1004, 1005} {
|
2013-02-27 22:58:41 -07:00
|
|
|
ift1, err := Interfaces()
|
|
|
|
if err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
2015-06-23 06:40:33 -06:00
|
|
|
ti := &testInterface{local: local, remote: remote}
|
2016-05-12 14:02:00 -06:00
|
|
|
if err := ti.setBroadcast(vid); err != nil {
|
2013-03-01 18:56:51 -07:00
|
|
|
t.Skipf("test requires external command: %v", err)
|
|
|
|
}
|
2013-02-27 22:58:41 -07:00
|
|
|
if err := ti.setup(); err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
} else {
|
|
|
|
time.Sleep(3 * time.Millisecond)
|
|
|
|
}
|
|
|
|
ift2, err := Interfaces()
|
|
|
|
if err != nil {
|
|
|
|
ti.teardown()
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
if len(ift2) <= len(ift1) {
|
|
|
|
for _, ifi := range ift1 {
|
|
|
|
t.Logf("before: %v", ifi)
|
|
|
|
}
|
|
|
|
for _, ifi := range ift2 {
|
|
|
|
t.Logf("after: %v", ifi)
|
|
|
|
}
|
|
|
|
ti.teardown()
|
|
|
|
t.Fatalf("got %v; want gt %v", len(ift2), len(ift1))
|
|
|
|
}
|
2015-06-23 06:40:33 -06:00
|
|
|
for _, ifi := range ift2 {
|
|
|
|
if ti.name != ifi.Name {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
ifat, err := ifi.Addrs()
|
|
|
|
if err != nil {
|
|
|
|
ti.teardown()
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
for _, ifa := range ifat {
|
|
|
|
if ip.Equal(ifa.(*IPNet).IP) {
|
|
|
|
ti.teardown()
|
|
|
|
t.Fatalf("got %v", ifa)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-02-27 22:58:41 -07:00
|
|
|
if err := ti.teardown(); err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
} else {
|
|
|
|
time.Sleep(3 * time.Millisecond)
|
|
|
|
}
|
|
|
|
ift3, err := Interfaces()
|
|
|
|
if err != nil {
|
2015-04-30 21:38:42 -06:00
|
|
|
t.Fatal(err)
|
2013-02-27 22:58:41 -07:00
|
|
|
}
|
|
|
|
if len(ift3) >= len(ift2) {
|
|
|
|
for _, ifi := range ift2 {
|
|
|
|
t.Logf("before: %v", ifi)
|
|
|
|
}
|
|
|
|
for _, ifi := range ift3 {
|
|
|
|
t.Logf("after: %v", ifi)
|
|
|
|
}
|
|
|
|
t.Fatalf("got %v; want lt %v", len(ift3), len(ift2))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|