Files
httprunner/hrp/pkg/gidevice/pcapd.go
2022-12-22 00:37:02 +08:00

98 lines
1.8 KiB
Go

package gidevice
import (
"log"
"github.com/httprunner/httprunner/v4/hrp/pkg/gidevice/pkg/libimobiledevice"
)
type PcapOptions struct {
All bool // capture all packets
Pid int // capture packets from specific PID
ProcName string // capture packets from specific process name
BundleID string // convert to PID first, then capture packets from the PID
}
type PcapOption func(*PcapOptions)
func WithPcapAll(all bool) PcapOption {
return func(opt *PcapOptions) {
opt.All = all
}
}
func WithPcapProcName(procName string) PcapOption {
return func(opt *PcapOptions) {
opt.ProcName = procName
}
}
func WithPcapPID(pid int) PcapOption {
return func(opt *PcapOptions) {
opt.Pid = pid
}
}
func WithPcapBundleID(bundleID string) PcapOption {
return func(opt *PcapOptions) {
opt.BundleID = bundleID
}
}
type pcapdClient struct {
stop chan struct{}
c *libimobiledevice.PcapdClient
}
func newPcapdClient(c *libimobiledevice.PcapdClient) *pcapdClient {
return &pcapdClient{
stop: make(chan struct{}),
c: c,
}
}
func (c *pcapdClient) Packet() <-chan []byte {
packetCh := make(chan []byte, 10)
go func() {
for {
select {
case <-c.stop:
return
default:
pkt, err := c.c.ReceivePacket()
if err != nil {
close(packetCh)
return
}
var payload []byte
_ = pkt.Unmarshal(&payload)
raw, err := c.c.GetPacket(payload)
if err != nil {
close(packetCh)
return
}
if raw == nil {
// filtered packet
continue
}
res, err := c.c.CreatePacket(raw)
if err != nil {
log.Println("failed to create packet")
return
}
packetCh <- res
}
}
}()
return packetCh
}
func (c *pcapdClient) Stop() {
select {
case <-c.stop:
default:
close(c.stop)
}
c.c.Close()
}