From aac1345d161588d2b0ba26a4533d7e4bceff293a Mon Sep 17 00:00:00 2001 From: Leonid Bugaev Date: Fri, 13 May 2016 17:31:39 +0500 Subject: [PATCH] Add Mac support --- Makefile | 4 +++ input_http_test.go | 3 +- input_raw_test.go | 10 +++--- raw_socket_listener/listener.go | 51 ++++++++++++++++++++++--------- raw_socket_listener/tcp_packet.go | 5 +++ 5 files changed, 51 insertions(+), 22 deletions(-) diff --git a/Makefile b/Makefile index 32fe0ba..4a8bc31 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ BENCHMARK = BenchmarkRAWInput TEST = TestRawListenerBench VERSION = DEV-$(shell date +%s) LDFLAGS = -ldflags "-X main.VERSION=$(VERSION) -extldflags \"-static\"" +MAC_LDFLAGS = -ldflags "-X main.VERSION=$(VERSION)" release: release-x64 @@ -14,6 +15,9 @@ release-x64: release-x86: docker run -v `pwd`:$(SOURCE_PATH) -t --env GOOS=linux --env GOARCH=386 -i gor go build $(LDFLAGS) && tar -czf gor_$(VERSION)_x86.tar.gz gor && rm gor +release-mac: + go build $(MAC_LDFLAGS) && tar -czf gor_$(VERSION)_x86.tar.gz gor + build: docker build -t gor . diff --git a/input_http_test.go b/input_http_test.go index 733e300..19f460e 100644 --- a/input_http_test.go +++ b/input_http_test.go @@ -41,8 +41,7 @@ func TestInputHTTPLargePayload(t *testing.T) { wg := new(sync.WaitGroup) quit := make(chan int) - // Generate 1000kb file - dd := exec.Command("dd", "if=/dev/urandom", "of=/tmp/large", "bs=1MB", "count=4") + dd := exec.Command("dd", "if=/dev/urandom", "of=/tmp/large", "bs=1", "count=4000000") err := dd.Run() if err != nil { log.Fatal("dd error:", err) diff --git a/input_raw_test.go b/input_raw_test.go index d61e72e..852a4a2 100644 --- a/input_raw_test.go +++ b/input_raw_test.go @@ -254,10 +254,10 @@ func TestInputRAWLargePayload(t *testing.T) { } wg := new(sync.WaitGroup) quit := make(chan int) - sizeKb := 100 + sizeB := 100 * 1000 // Generate 100kb file - dd := exec.Command("dd", "if=/dev/urandom", "of=/tmp/large", "bs=1KB", "count="+strconv.Itoa(sizeKb)) + dd := exec.Command("dd", "if=/dev/urandom", "of=/tmp/large", "bs=1", "count="+strconv.Itoa(sizeB)) err := dd.Run() if err != nil { log.Fatal("dd error:", err) @@ -267,7 +267,7 @@ func TestInputRAWLargePayload(t *testing.T) { defer req.Body.Close() body, _ := ioutil.ReadAll(req.Body) - if len(body) != sizeKb*1000 { + if len(body) != sizeB { t.Error("File size should be 1mb:", len(body)) } @@ -285,8 +285,8 @@ func TestInputRAWLargePayload(t *testing.T) { // n, _ := req.Body.Read(buf) // body := buf[0:n] - if len(body) != sizeKb*1000 { - t.Errorf("File size should be %d bytes: %d", sizeKb*1000, len(body)) + if len(body) != sizeB { + t.Errorf("File size should be %d bytes: %d", sizeB, len(body)) } wg.Done() diff --git a/raw_socket_listener/listener.go b/raw_socket_listener/listener.go index 8a363f8..0148fef 100644 --- a/raw_socket_listener/listener.go +++ b/raw_socket_listener/listener.go @@ -17,7 +17,7 @@ import ( "encoding/binary" "fmt" "github.com/google/gopacket" - _ "github.com/google/gopacket/layers" + "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" "io" "log" @@ -27,6 +27,7 @@ import ( "strings" "sync" "time" + "runtime" ) var _ = fmt.Println @@ -268,6 +269,11 @@ func (t *Listener) readPcap() { log.Fatal(err) } + bpfSupported := true + if runtime.GOOS == "darwin" { + bpfSupported = false + } + var wg sync.WaitGroup wg.Add(len(devices)) @@ -285,22 +291,23 @@ func (t *Listener) readPcap() { t.pcapHandles = append(t.pcapHandles, handle) t.mu.Unlock() - bpf := "tcp port " + strconv.Itoa(int(t.port)) - - // log.Println("Applying bpf programm:", bpf, " Device:", device.Name) - if err := handle.SetBPFFilter(bpf); err != nil { - log.Println("BPF filter error:", err, "Device:", device.Name) - wg.Done() - return + if bpfSupported { + bpf := "tcp port " + strconv.Itoa(int(t.port)) + if err := handle.SetBPFFilter(bpf); err != nil { + log.Println("BPF filter error:", err, "Device:", device.Name) + wg.Done() + return + } } - // log.Println("BPF appplied", device.Name) - - source := gopacket.NewPacketSource(handle, handle.LinkType()) + linkType := handle.LinkType() + source := gopacket.NewPacketSource(handle, linkType) source.Lazy = true source.NoCopy = true wg.Done() + var data, srcIP []byte + for { packet, err := source.NextPacket() @@ -310,11 +317,14 @@ func (t *Listener) readPcap() { continue } - // Skip ethernet layer, 14 bytes - data := packet.Data()[14:] - version := uint8(data[0]) >> 4 + if linkType == layers.LinkTypeEthernet { + // Skip ethernet layer, 14 bytes + data = packet.Data()[14:] + } else if linkType == layers.LinkTypeNull || linkType == layers.LinkTypeLoop { + data = packet.Data()[4:] + } - var srcIP []byte + version := uint8(data[0]) >> 4 if version == 4 { ihl := uint8(data[0]) & 0x0F @@ -347,6 +357,17 @@ func (t *Listener) readPcap() { // We need only packets with data inside // Check that the buffer is larger than the size of the TCP header if len(data) > int(dataOffset*4) { + if !bpfSupported { + destPort := binary.BigEndian.Uint16(data[2:4]) + srcPort := binary.BigEndian.Uint16(data[0:2]) + + // log.Println(t.port, destPort, srcPort, packet) + + if destPort != t.port && srcPort != t.port { + continue + } + } + newBuf := make([]byte, len(data)+16) copy(newBuf[:16], srcIP) copy(newBuf[16:], data) diff --git a/raw_socket_listener/tcp_packet.go b/raw_socket_listener/tcp_packet.go index 3631dc6..d11e4fd 100644 --- a/raw_socket_listener/tcp_packet.go +++ b/raw_socket_listener/tcp_packet.go @@ -4,8 +4,11 @@ import ( "encoding/binary" "strconv" "strings" + "log" ) +var _ = log.Println + // TCP Flags const ( fFIN = 1 << iota @@ -69,6 +72,8 @@ func (t *TCPPacket) ParseBasic() { t.Ack = binary.BigEndian.Uint32(t.Raw[8:12]) t.DataOffset = (t.Raw[12] & 0xF0) >> 4 + // log.Println("DataOffset:", t.DataOffset, t.DestPort, t.SrcPort, t.Seq, t.Ack) + t.Data = t.Raw[t.DataOffset*4:] }