Fix MacOS compilation

This commit is contained in:
Leonid Bugaev
2021-06-29 21:11:31 +03:00
parent 9468978353
commit ad43405793
4 changed files with 197 additions and 99 deletions
+10 -95
View File
@@ -5,111 +5,26 @@ import (
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/afpacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"golang.org/x/net/bpf"
_ "github.com/google/gopacket/layers"
)
type afpacketHandle struct {
TPacket *afpacket.TPacket
}
func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int,
useVLAN bool, timeout time.Duration) (*afpacketHandle, error) {
h := &afpacketHandle{}
var err error
if device == "any" {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptFrameSize(snaplen),
afpacket.OptBlockSize(block_size),
afpacket.OptNumBlocks(num_blocks),
afpacket.OptAddVLANHeader(useVLAN),
afpacket.OptPollTimeout(timeout),
afpacket.SocketRaw,
afpacket.TPacketVersion3)
} else {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptInterface(device),
afpacket.OptFrameSize(snaplen),
afpacket.OptBlockSize(block_size),
afpacket.OptNumBlocks(num_blocks),
afpacket.OptAddVLANHeader(useVLAN),
afpacket.OptPollTimeout(timeout),
afpacket.SocketRaw,
afpacket.TPacketVersion3)
}
return h, err
return nil, fmt.Errorf("Not implemented")
}
func afpacketComputeSize(targetSizeMb int, snaplen int, pageSize int) (
frameSize int, blockSize int, numBlocks int, err error) {
return 0, 0, 0, fmt.Errorf("Not implemented")
}
type afpacketHandle struct{}
// ZeroCopyReadPacketData satisfies ZeroCopyPacketDataSource interface
func (h *afpacketHandle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
return h.TPacket.ZeroCopyReadPacketData()
return nil, gopacket.CaptureInfo{}, fmt.Errorf("Not implemented")
}
// SetBPFFilter translates a BPF filter string into BPF RawInstruction and applies them.
func (h *afpacketHandle) SetBPFFilter(filter string, snaplen int) (err error) {
pcapBPF, err := pcap.CompileBPFFilter(layers.LinkTypeEthernet, snaplen, filter)
if err != nil {
return err
}
bpfIns := []bpf.RawInstruction{}
for _, ins := range pcapBPF {
bpfIns2 := bpf.RawInstruction{
Op: ins.Code,
Jt: ins.Jt,
Jf: ins.Jf,
K: ins.K,
}
bpfIns = append(bpfIns, bpfIns2)
}
if h.TPacket.SetBPF(bpfIns); err != nil {
return err
}
return h.TPacket.SetBPF(bpfIns)
}
// LinkType returns ethernet link type.
func (h *afpacketHandle) LinkType() layers.LinkType {
return layers.LinkTypeEthernet
}
// Close will close afpacket source.
func (h *afpacketHandle) Close() {
h.TPacket.Close()
}
// SocketStats prints received, dropped, queue-freeze packet stats.
func (h *afpacketHandle) SocketStats() (as afpacket.SocketStats, asv afpacket.SocketStatsV3, err error) {
return h.TPacket.SocketStats()
}
// afpacketComputeSize computes the block_size and the num_blocks in such a way that the
// allocated mmap buffer is close to but smaller than target_size_mb.
// The restriction is that the block_size must be divisible by both the
// frame size and page size.
func afpacketComputeSize(targetSizeMb int, snaplen int, pageSize int) (
frameSize int, blockSize int, numBlocks int, err error) {
if snaplen < pageSize {
frameSize = pageSize / (pageSize / snaplen)
} else {
frameSize = (snaplen/pageSize + 1) * pageSize
}
// 128 is the default from the gopacket library so just use that
blockSize = frameSize * 128
numBlocks = (targetSizeMb * 1024 * 1024) / blockSize
fmt.Println(blockSize, (targetSizeMb * 1024 * 1024), pageSize, snaplen)
if numBlocks == 0 {
return 0, 0, 0, fmt.Errorf("Interface buffersize is too small")
}
return frameSize, blockSize, numBlocks, nil
return fmt.Errorf("Not implemented")
}
+186
View File
@@ -0,0 +1,186 @@
// +build linux
package main
import (
"flag"
"fmt"
"log"
"os"
"runtime/pprof"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/afpacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"golang.org/x/net/bpf"
_ "github.com/google/gopacket/layers"
)
var (
iface = flag.String("i", "any", "Interface to read from")
cpuprofile = flag.String("cpuprofile", "", "If non-empty, write CPU profile here")
snaplen = flag.Int("s", 0, "Snaplen, if <= 0, use 65535")
bufferSize = flag.Int("b", 8, "Interface buffersize (MB)")
filter = flag.String("f", "port not 22", "BPF filter")
count = flag.Int64("c", -1, "If >= 0, # of packets to capture before returning")
verbose = flag.Int64("log_every", 1, "Write a log every X packets")
addVLAN = flag.Bool("add_vlan", false, "If true, add VLAN header")
)
type afpacketHandle struct {
TPacket *afpacket.TPacket
}
func newAfpacketHandle(device string, snaplen int, block_size int, num_blocks int,
useVLAN bool, timeout time.Duration) (*afpacketHandle, error) {
h := &afpacketHandle{}
var err error
if device == "any" {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptFrameSize(snaplen),
afpacket.OptBlockSize(block_size),
afpacket.OptNumBlocks(num_blocks),
afpacket.OptAddVLANHeader(useVLAN),
afpacket.OptPollTimeout(timeout),
afpacket.SocketRaw,
afpacket.TPacketVersion3)
} else {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptInterface(device),
afpacket.OptFrameSize(snaplen),
afpacket.OptBlockSize(block_size),
afpacket.OptNumBlocks(num_blocks),
afpacket.OptAddVLANHeader(useVLAN),
afpacket.OptPollTimeout(timeout),
afpacket.SocketRaw,
afpacket.TPacketVersion3)
}
return h, err
}
// ZeroCopyReadPacketData satisfies ZeroCopyPacketDataSource interface
func (h *afpacketHandle) ZeroCopyReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
return h.TPacket.ZeroCopyReadPacketData()
}
// SetBPFFilter translates a BPF filter string into BPF RawInstruction and applies them.
func (h *afpacketHandle) SetBPFFilter(filter string, snaplen int) (err error) {
pcapBPF, err := pcap.CompileBPFFilter(layers.LinkTypeEthernet, snaplen, filter)
if err != nil {
return err
}
bpfIns := []bpf.RawInstruction{}
for _, ins := range pcapBPF {
bpfIns2 := bpf.RawInstruction{
Op: ins.Code,
Jt: ins.Jt,
Jf: ins.Jf,
K: ins.K,
}
bpfIns = append(bpfIns, bpfIns2)
}
if h.TPacket.SetBPF(bpfIns); err != nil {
return err
}
return h.TPacket.SetBPF(bpfIns)
}
// LinkType returns ethernet link type.
func (h *afpacketHandle) LinkType() layers.LinkType {
return layers.LinkTypeEthernet
}
// Close will close afpacket source.
func (h *afpacketHandle) Close() {
h.TPacket.Close()
}
// SocketStats prints received, dropped, queue-freeze packet stats.
func (h *afpacketHandle) SocketStats() (as afpacket.SocketStats, asv afpacket.SocketStatsV3, err error) {
return h.TPacket.SocketStats()
}
// afpacketComputeSize computes the block_size and the num_blocks in such a way that the
// allocated mmap buffer is close to but smaller than target_size_mb.
// The restriction is that the block_size must be divisible by both the
// frame size and page size.
func afpacketComputeSize(targetSizeMb int, snaplen int, pageSize int) (
frameSize int, blockSize int, numBlocks int, err error) {
if snaplen < pageSize {
frameSize = pageSize / (pageSize / snaplen)
} else {
frameSize = (snaplen/pageSize + 1) * pageSize
}
// 128 is the default from the gopacket library so just use that
blockSize = frameSize * 128
numBlocks = (targetSizeMb * 1024 * 1024) / blockSize
if numBlocks == 0 {
return 0, 0, 0, fmt.Errorf("Interface buffersize is too small")
}
return frameSize, blockSize, numBlocks, nil
}
func main() {
flag.Parse()
if *cpuprofile != "" {
log.Printf("Writing CPU profile to %q", *cpuprofile)
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal(err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatal(err)
}
defer pprof.StopCPUProfile()
}
log.Printf("Starting on interface %q", *iface)
if *snaplen <= 0 {
*snaplen = 65535
}
err = afpacketHandle.SetBPFFilter(*filter, *snaplen)
if err != nil {
log.Fatal(err)
}
source := gopacket.ZeroCopyPacketDataSource(afpacketHandle)
defer afpacketHandle.Close()
bytes := uint64(0)
packets := uint64(0)
for ; *count != 0; *count-- {
data, _, err := source.ZeroCopyReadPacketData()
if err != nil {
log.Fatal(err)
}
bytes += uint64(len(data))
packets++
if *count%*verbose == 0 {
_, afpacketStats, err := afpacketHandle.SocketStats()
if err != nil {
log.Println(err)
}
log.Printf("Read in %d bytes in %d packets", bytes, packets)
log.Printf("Stats {received dropped queue-freeze}: %d", afpacketStats)
}
}
}
func (l *Listener) PcapHandle(ifi pcap.Interface) (handle *pcap.Handle, err error) {
szFrame, szBlock, numBlocks, err := afpacketComputeSize(*bufferSize, *snaplen, os.Getpagesize())
if err != nil {
log.Fatal(err)
}
handle, err = newAfpacketHandle(*ifi, szFrame, szBlock, numBlocks, *addVLAN, pcap.BlockForever)
return afpacketHandle
}
+1 -1
View File
@@ -15,6 +15,6 @@ require (
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/stretchr/testify v1.5.1
golang.org/x/net v0.0.0-20200707034311-ab3426394381 // indirect
golang.org/x/net v0.0.0-20200707034311-ab3426394381
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
)
-3
View File
@@ -29,8 +29,6 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gopacket v1.1.18 h1:lum7VRA9kdlvBi7/v2p7/zcbkduHaCH/SVVyurs7OpY=
github.com/google/gopacket v1.1.18/go.mod h1:UdDNZ1OO62aGYVnPhxT1U6aI7ukYtA/kB8vaU0diBUM=
github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325 h1:YmIcZ5Var3BAQ64AW98Iiys5Ih4fiU0xK41+8isC5Ec=
github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
@@ -91,7 +89,6 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgN
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=