You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bcap/libpcap/libpcap.go

91 lines
1.7 KiB
Go

1 month ago
package libpcap
import (
"context"
1 month ago
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
)
type NetCatch struct {
eth string
host string
sentence string
fn func(gopacket.Packet)
*pcap.Handle
ctx context.Context
stopFn context.CancelFunc
1 month ago
}
func (n *NetCatch) SetRecall(fn func(p gopacket.Packet)) {
n.fn = fn
}
func (n *NetCatch) Stop() {
n.stopFn()
}
1 month ago
func FindAllDevs() ([]pcap.Interface, error) {
return pcap.FindAllDevs()
}
func NewCatch(host string, sentence string) (*NetCatch, error) {
ifs, err := pcap.FindAllDevs()
if err != nil {
return nil, err
}
eth := ""
for _, v := range ifs {
if host == "127.0.0.1" && v.Name == "\\Device\\NPF_Loopback" {
eth = v.Name
}
for _, addr := range v.Addresses {
if addr.IP.String() == host {
eth = v.Name
}
}
}
if len(eth) == 0 {
return nil, fmt.Errorf("cannot found eth")
}
nc := new(NetCatch)
nc.host = host
nc.eth = eth
nc.sentence = sentence
nc.ctx, nc.stopFn = context.WithCancel(context.Background())
1 month ago
return nc, nil
}
func NewCatchEth(eth string, sentence string) (*NetCatch, error) {
nc := new(NetCatch)
nc.eth = eth
nc.sentence = sentence
nc.ctx, nc.stopFn = context.WithCancel(context.Background())
1 month ago
return nc, nil
}
func (n *NetCatch) Run() error {
if n.eth == "" {
return fmt.Errorf("no pcap device")
}
handle, err := pcap.OpenLive(n.eth, 65535, true, pcap.BlockForever)
if err != nil {
return err
}
n.Handle = handle
if err = handle.SetBPFFilter(n.sentence); err != nil {
return err
}
pks := gopacket.NewPacketSource(handle, handle.LinkType())
for {
select {
case packet := <-pks.Packets():
if n.fn != nil {
n.fn(packet)
}
case <-n.ctx.Done():
return nil
1 month ago
}
}
}