当前位置: > > > > 无法使用 gopacket 监听连接的套接字
无法使用 gopacket 监听连接的套接字
来源:stackoverflow
2024-04-22 18:09:36
0浏览
收藏
本篇文章向大家介绍《无法使用 gopacket 监听连接的套接字》,主要包括,具有一定的参考价值,需要的朋友可以参考一下。
问题内容
我正在尝试使用 gopacket 来监听套接字并打印 tcp 数据包有效负载。如果我先启动 snooper 应用程序,然后连接 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”下方:
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
}
}
}
到这里,我们也就讲完了《无法使用 gopacket 监听连接的套接字》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注米云公众号,带你了解更多关于的知识点!
