-
Notifications
You must be signed in to change notification settings - Fork 8
/
afpacket_linux.go
76 lines (63 loc) · 1.99 KB
/
afpacket_linux.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// +build linux
package devices
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"
)
// AFPacketHandle is an implementation of a gopacket PacketSource.
type AFPacketHandle struct {
TPacket *afpacket.TPacket
}
func newAFPacketHandle(device string, frameSize int, blockSize int, blockCount int, timeout time.Duration) (*AFPacketHandle, error) {
var err error
h := &AFPacketHandle{}
if device == "any" {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptFrameSize(frameSize),
afpacket.OptBlockSize(blockSize),
afpacket.OptNumBlocks(blockCount),
afpacket.OptPollTimeout(timeout))
} else {
h.TPacket, err = afpacket.NewTPacket(
afpacket.OptInterface(device),
afpacket.OptFrameSize(frameSize),
afpacket.OptBlockSize(blockSize),
afpacket.OptNumBlocks(blockCount),
afpacket.OptPollTimeout(timeout))
}
return h, err
}
// ReadPacketData is an implementation of a gopacket PacketSource's ReadPacketData method.
func (h *AFPacketHandle) ReadPacketData() (data []byte, ci gopacket.CaptureInfo, err error) {
return h.TPacket.ReadPacketData()
}
// SetBPFFilter is an implementation of a gopacket PacketSource's SetBPFFilter method.
func (h *AFPacketHandle) SetBPFFilter(filter string, frameSize int) (_ error) {
pcapBPF, err := pcap.CompileBPFFilter(h.LinkType(), frameSize, filter)
if err != nil {
return err
}
instructions := []bpf.RawInstruction{}
for _, ins := range pcapBPF {
rawins := bpf.RawInstruction{
Op: ins.Code,
Jt: ins.Jt,
Jf: ins.Jf,
K: ins.K,
}
instructions = append(instructions, rawins)
}
return h.TPacket.SetBPF(instructions)
}
// LinkType is an implementation of a gopacket PacketSource's LinkType method.
func (h *AFPacketHandle) LinkType() layers.LinkType {
return layers.LinkTypeEthernet
}
// Close is an implementation of a gopacket PacketSource's Close method.
func (h *AFPacketHandle) Close() {
h.TPacket.Close()
}