package main
import (
"fmt"
"strings"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
// 根据名称查找网卡设备名
func FindDevicesByName(name string, show bool) (string, error) {
devices, err := pcap.FindAllDevs()
if err != nil {
return "", err
}
for _, device := range devices {
if show {
fmt.Println("\nName: ", device.Name)
fmt.Println("Description: ", device.Description)
for _, address := range device.Addresses {
fmt.Println("- IP address: ", address.IP)
fmt.Println("- Subnet mask: ", address.Netmask)
}
}
if device.Description == name {
return device.Name, nil
}
}
return "", fmt.Errorf("Not found Devices!")
}
type OpenLiveCg struct {
Devices string
Max_len int32
Promisc bool
Timeout time.Duration
}
type CaptureConfig struct {
LiveTo OpenLiveCg //驱动配置
InControl chan string //抓取命令管道
OffCap chan bool //关闭抓取函数
OffFunc chan bool //关闭函数
OutData chan interface{}
OutError chan error
InFilter chan string //抓取过滤
OpenCap bool
}
func HandleDump(handle *pcap.Handle, cc *CaptureConfig, method string) {
if cc.OpenCap {
cc.OffCap <- true
} else {
cc.OpenCap = true
}
// 对 抓包进行发送到管道
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
switch method {
case "http":
tcpLayer := packet.Layer(layers.LayerTypeTCP)
if tcpLayer != nil {
tcp, _ := tcpLayer.(*layers.TCP)
if strings.Contains(tcp.DstPort.String(), "http") {
cc.OutData <- tcp
}
}
default:
cc.OutData <- packet
}
select {
case <-cc.OffCap:
return
default:
}
}
}
// 处理抓包函数
func PcapDumpCore(cc *CaptureConfig) {
// 开启监听,第一个参数为驱动名称,第二个为最大抓包size,1600字节,true 为混杂模式,都抓,第四个为超时时间
handle, err := pcap.OpenLive(cc.LiveTo.Devices, cc.LiveTo.Max_len, cc.LiveTo.Promisc, cc.LiveTo.Timeout)
if err != nil {
panic(err)
// cc.OutError <- err
}
// 关闭是释放空间并关闭监听
defer func() {
handle.Close()
close(cc.InControl)
close(cc.OffCap)
close(cc.OutData)
close(cc.OutError)
close(cc.InFilter)
close(cc.OffFunc)
}()
// 处理过滤命令
for {
select {
case filter := <-cc.InFilter:
err := handle.SetBPFFilter(filter)
if err != nil {
cc.OutError <- err
}
case Com := <-cc.InControl:
HandleDump(handle, cc, Com)
// 关闭函数
case <-cc.OffFunc:
return
default:
}
}
}
GoPacket实现高性能抓包模块——可扩展
最新推荐文章于 2024-03-18 14:26:20 发布