You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
1.7 KiB
87 lines
1.7 KiB
6 months ago
|
package core
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"eruhs/core/parser"
|
||
|
"github.com/dustin/go-humanize"
|
||
|
"github.com/google/gopacket"
|
||
|
"github.com/google/gopacket/pcap"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type DataPack struct {
|
||
|
TotalLength int
|
||
|
LayerStack []parser.Layer
|
||
|
}
|
||
|
|
||
|
func (d *DataPack) AddLayer(layer parser.Layer) {
|
||
|
d.LayerStack = append(d.LayerStack, layer)
|
||
|
}
|
||
|
|
||
|
type Capture struct {
|
||
|
handle *pcap.Handle
|
||
|
started bool
|
||
|
stopFunc func()
|
||
|
callback func(pack *DataPack)
|
||
|
errCallback func(err error)
|
||
|
}
|
||
|
|
||
|
func NewCapture(callback func(pack *DataPack), errCallback func(err error)) *Capture {
|
||
|
return &Capture{
|
||
|
callback: callback,
|
||
|
errCallback: errCallback,
|
||
|
started: false,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// StartCaptureOnDevice 传入设备ID,启动抓包
|
||
|
func (c *Capture) StartCaptureOnDevice(device string) {
|
||
|
if c.started {
|
||
|
return
|
||
|
} else {
|
||
|
c.started = true
|
||
|
}
|
||
|
|
||
|
handle, err := pcap.OpenLive(device, 4*humanize.KByte, false, 1*time.Second)
|
||
|
if err != nil {
|
||
|
c.errCallback(err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
c.handle = handle
|
||
|
ctx, cancel := context.WithCancel(context.Background())
|
||
|
c.stopFunc = cancel
|
||
|
|
||
|
// 开启一个goroutine协程,实时读取数据包,并在抓取到数据包后调用callback,继续下一步的解析操作
|
||
|
go func(ctx context.Context) {
|
||
|
defer c.handle.Close()
|
||
|
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
||
|
for packet := range packetSource.Packets() {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
return
|
||
|
default:
|
||
|
parsedPack, err := c.handlePacket(packet)
|
||
|
if err != nil {
|
||
|
if parsedPack != nil {
|
||
|
c.callback(parsedPack)
|
||
|
} else {
|
||
|
c.errCallback(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
c.callback(parsedPack)
|
||
|
}
|
||
|
}
|
||
|
}(ctx)
|
||
|
}
|
||
|
|
||
|
func (c *Capture) Pause() {
|
||
|
|
||
|
}
|
||
|
|
||
|
func (c *Capture) Stop() {
|
||
|
c.stopFunc()
|
||
|
c.started = false
|
||
|
}
|