无法使用gopacket来窥探已连接的套接字



我正在尝试使用gopacket来窥探套接字并打印tcp数据包有效负载。如果我先启动窥探者应用程序,然后连接一个tcp套接字,事情就会正常工作。如果在snooper应用程序启动时套接字已经连接,则不会打印任何内容。

如果我传递这个选项-assembly_debug_log,我得到这样的输出:

2022/04/22 11:36:10 assembly.go:582: [127.0.0.1->127.0.0.1 43584->80] waiting for start, storing into connection
2022/04/22 11:36:10 assembly.go:582: [127.0.0.1->127.0.0.1 80->43584] waiting for start, storing into connection
2022/04/22 11:36:10 assembly.go:537: ignoring useless packet
2022/04/22 11:36:12 assembly.go:582: [127.0.0.1->127.0.0.1 43584->80] waiting for start, storing into connection
2022/04/22 11:36:12 assembly.go:582: [127.0.0.1->127.0.0.1 80->43584] waiting for start, storing into connection
2022/04/22 11:36:12 assembly.go:537: ignoring useless packet

调试信息在assembly.go:

if conn.nextSeq == invalidSequence

我没有办法设置conn.nextSeq的值。

因此,这个汇编程序似乎将保存数据包,直到收到SYN数据包,因为连接已经建立,所以它不会。

是否有一种方法可以从已经建立的套接字连接中打印tcp数据包?

代码如下:

package main
import (
"io"
"log"
"github.com/google/gopacket"
"github.com/google/gopacket/examples/util"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/gopacket/tcpassembly"
"github.com/google/gopacket/tcpassembly/tcpreader"
)
type myStream struct {
r tcpreader.ReaderStream
}
func (ms *myStream) run() {
buf := make([]byte, 4096)
for {
n, err := ms.r.Read(buf)
if err == io.EOF {
return
} else if err != nil {
log.Fatal(err)
}
log.Println(string(buf[:n]))
}
}
type myStreamFactory struct{}
func (msf *myStreamFactory) New(_, _ gopacket.Flow) tcpassembly.Stream {
stream := &myStream{tcpreader.NewReaderStream()}
go stream.run()
return &stream.r
}
func main() {
defer util.Run()()
flags := log.Flags()
log.SetFlags(flags | log.Lshortfile)
handle, err := pcap.OpenLive("lo", 262144, true, pcap.BlockForever)
if err != nil {
log.Fatal(err)
}
if err = handle.SetBPFFilter("tcp and port 80"); err != nil {
log.Fatal(err)
}
streamFactory := &myStreamFactory{}
streamPool := tcpassembly.NewStreamPool(streamFactory)
assembler := tcpassembly.NewAssembler(streamPool)
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
log.Println("Unusable packet")
continue
}
tcp := packet.TransportLayer().(*layers.TCP)
assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp)
}
}

我在创建新流后添加了对assembler.FlushWithOptions的调用,现在似乎工作正常。

package main
import (
"io"
"log"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/examples/util"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/gopacket/tcpassembly"
"github.com/google/gopacket/tcpassembly/tcpreader"
)
type myStream struct {
r tcpreader.ReaderStream
}
func (ms *myStream) run() {
buf := make([]byte, 4096)
for {
n, err := ms.r.Read(buf)
if err == io.EOF {
return
} else if err != nil {
log.Fatal(err)
}
log.Println(string(buf[:n]))
}
}
type myStreamFactory struct {
iWantFlush bool
}
func (msf *myStreamFactory) New(_, _ gopacket.Flow) tcpassembly.Stream {
stream := &myStream{tcpreader.NewReaderStream()}
go stream.run()
msf.iWantFlush = true
return &stream.r
}
func main() {
defer util.Run()()
flags := log.Flags()
log.SetFlags(flags | log.Lshortfile)
handle, err := pcap.OpenLive("lo", 262144, true, pcap.BlockForever)
if err != nil {
log.Fatal(err)
}
if err = handle.SetBPFFilter("tcp and port 80"); err != nil {
log.Fatal(err)
}
streamFactory := &myStreamFactory{}
streamPool := tcpassembly.NewStreamPool(streamFactory)
assembler := tcpassembly.NewAssembler(streamPool)
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
for packet := range packetSource.Packets() {
if packet.NetworkLayer() == nil || packet.TransportLayer() == nil || packet.TransportLayer().LayerType() != layers.LayerTypeTCP {
log.Println("Unusable packet")
continue
}
tcp := packet.TransportLayer().(*layers.TCP)
assembler.AssembleWithTimestamp(packet.NetworkLayer().NetworkFlow(), tcp, packet.Metadata().Timestamp)
if streamFactory.iWantFlush {
assembler.FlushWithOptions(tcpassembly.FlushOptions{time.Now(), false})
streamFactory.iWantFlush = false
}
}
}

相关内容

  • 没有找到相关文章

最新更新