From 965ca414a683f3a1efbc21041d534715f8fc9e8d Mon Sep 17 00:00:00 2001 From: Song Gao Date: Sun, 8 Nov 2015 21:54:47 +0000 Subject: [PATCH 1/3] add ipv4 broadcast test --- ipv4_test.go | 89 ++++++++++++++++++++++++++++++++++++++++++++++ ipv4_test_linux.go | 16 +++++++++ ipv4_test_other.go | 12 +++++++ 3 files changed, 117 insertions(+) create mode 100644 ipv4_test.go create mode 100644 ipv4_test_linux.go create mode 100644 ipv4_test_other.go diff --git a/ipv4_test.go b/ipv4_test.go new file mode 100644 index 0000000..5c38901 --- /dev/null +++ b/ipv4_test.go @@ -0,0 +1,89 @@ +package water + +import ( + "net" + "os/exec" + "testing" + "time" + + "github.com/songgao/water/waterutil" +) + +const BUFFERSIZE = 1522 + +func startTimeout(ch chan<- bool, t time.Duration) { + go func() { + time.Sleep(t) + ch <- true + }() +} + +func startRead(ch chan<- []byte, ifce *Interface) { + go func() { + for { + buffer := make([]byte, BUFFERSIZE) + _, err := ifce.Read(buffer) + if err == nil { + ch <- buffer + } + } + }() +} + +func startBroadcast(t *testing.T, dst net.IP) { + if err := exec.Command("ping", "-b", "-c", "2", dst.String()).Start(); err != nil { + t.Fatal(err) + } +} + +func TestBroadcast(t *testing.T) { + var ( + self = net.IPv4(10, 0, 42, 1) + mask = net.IPv4Mask(255, 255, 255, 0) + brd = net.IPv4(10, 0, 42, 255) + ) + + ifce, err := NewTAP("test") + if err != nil { + t.Fatal(err) + } + + setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) + startBroadcast(t, brd) + + dataCh := make(chan []byte, 8) + startRead(dataCh, ifce) + + timeout := make(chan bool, 1) + startTimeout(timeout, time.Second*8) + +readFrame: + for { + select { + case buffer := <-dataCh: + ethertype := waterutil.MACEthertype(buffer) + if ethertype != waterutil.IPv4 { + continue readFrame + } + if !waterutil.IsBroadcast(waterutil.MACDestination(buffer)) { + continue readFrame + } + packet := waterutil.MACPayload(buffer) + if !waterutil.IsIPv4(packet) { + continue readFrame + } + if !waterutil.IPv4Source(packet).Equal(self) { + continue readFrame + } + if !waterutil.IPv4Destination(packet).Equal(brd) { + continue readFrame + } + if waterutil.IPv4Protocol(packet) != waterutil.ICMP { + continue readFrame + } + break readFrame + case <-timeout: + t.Fatal("Waiting for broadcast packet timeout") + } + } +} diff --git a/ipv4_test_linux.go b/ipv4_test_linux.go new file mode 100644 index 0000000..b5b680c --- /dev/null +++ b/ipv4_test_linux.go @@ -0,0 +1,16 @@ +package water + +import ( + "net" + "os/exec" + "testing" +) + +func setupIfce(t *testing.T, ipNet net.IPNet, dev string) { + if err := exec.Command("ip", "link", "set", dev, "up").Run(); err != nil { + t.Fatal(err) + } + if err := exec.Command("ip", "addr", "add", ipNet.String(), "dev", dev).Run(); err != nil { + t.Fatal(err) + } +} diff --git a/ipv4_test_other.go b/ipv4_test_other.go new file mode 100644 index 0000000..d70a50f --- /dev/null +++ b/ipv4_test_other.go @@ -0,0 +1,12 @@ +// +build !linux + +package water + +import ( + "net" + "testing" +) + +func setupIfce(t *testing.T, ipNet net.IPNet, dev string) { + t.Fatal("unsupported platform") +} From d8e4f41ac8da9c1133cadaeed61bdef703ca8f51 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Wed, 11 Nov 2015 22:12:44 +0000 Subject: [PATCH 2/3] use time.Timer --- ipv4_test.go | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/ipv4_test.go b/ipv4_test.go index 5c38901..84cb523 100644 --- a/ipv4_test.go +++ b/ipv4_test.go @@ -11,13 +11,6 @@ import ( const BUFFERSIZE = 1522 -func startTimeout(ch chan<- bool, t time.Duration) { - go func() { - time.Sleep(t) - ch <- true - }() -} - func startRead(ch chan<- []byte, ifce *Interface) { go func() { for { @@ -54,8 +47,7 @@ func TestBroadcast(t *testing.T) { dataCh := make(chan []byte, 8) startRead(dataCh, ifce) - timeout := make(chan bool, 1) - startTimeout(timeout, time.Second*8) + timeout := time.NewTimer(8 * time.Second).C readFrame: for { From acc2c8967a6ba6b45035155a6403292bf311e394 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Thu, 19 Nov 2015 19:24:13 +0000 Subject: [PATCH 3/3] return error instead of panic() --- ipv4_test.go | 2 +- syscalls_other.go | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ipv4_test.go b/ipv4_test.go index 84cb523..f855521 100644 --- a/ipv4_test.go +++ b/ipv4_test.go @@ -38,7 +38,7 @@ func TestBroadcast(t *testing.T) { ifce, err := NewTAP("test") if err != nil { - t.Fatal(err) + t.Fatalf("creating TAP error: %v\n", err) } setupIfce(t, net.IPNet{IP: self, Mask: mask}, ifce.Name()) diff --git a/syscalls_other.go b/syscalls_other.go index a38ce85..ace8c3c 100644 --- a/syscalls_other.go +++ b/syscalls_other.go @@ -2,10 +2,12 @@ package water +import "errors" + func newTAP(ifName string) (ifce *Interface, err error) { - panic("water: tap interface not implemented on this platform") + return nil, errors.New("tap interface not implemented on this platform") } func newTUN(ifName string) (ifce *Interface, err error) { - panic("water: tap interface not implemented on this platform") + return nil, errors.New("tap interface not implemented on this platform") }