From 965ca414a683f3a1efbc21041d534715f8fc9e8d Mon Sep 17 00:00:00 2001 From: Song Gao Date: Sun, 8 Nov 2015 21:54:47 +0000 Subject: [PATCH] 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") +}