当我从s3客户端获取pcap文件时,我需要生成gopacket的packetsource来读取其中的数据包。但是我只在gopacket文档中找到了openofflinefile函数,我该如何用[]byte(从s3文件读取)生成packetsource。
我已经阅读了gopacket中openofflinefile函数的源代码,但我仍然很困惑,因为我不熟悉uintptr,我可以直接用[]byte生成一个unitptr,然后用它来生成packetsource吗?
func openOffline(file string) (handle *Handle, err error) { err = LoadWinPCAP() if err != nil { return nil, err } buf := make([]byte, errorBufferSize) f, err := syscall.BytePtrFromString(file) if err != nil { return nil, err } var cptr uintptr if pcapOpenOfflineWithTstampPrecisionPtr == 0 { cptr, _, _ = syscall.Syscall(pcapOpenOfflinePtr, 2, uintptr(unsafe.Pointer(f)), uintptr(unsafe.Pointer(&buf[0])), 0) } else { cptr, _, _ = syscall.Syscall(pcapOpenOfflineWithTstampPrecisionPtr, 3, uintptr(unsafe.Pointer(f)), uintptr(pcapTstampPrecisionNano), uintptr(unsafe.Pointer(&buf[0]))) } if cptr == 0 { return nil, errors.New(byteSliceToString(buf)) } h := &Handle{cptr: pcapTPtr(cptr)} return h, nil }
github.com/google/gopacket/pcapgo
如果 github.com/google/gopacket/pcapgo
包支持该文件格式,请考虑使用它,因为它很容易:
package main import ( "bytes" "io" "log" "os" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcapgo" ) func main() { f, err := os.open("test.pcap") if err != nil { panic(err) } // as described in the question, buf is read from s3 file. in order to // make this demo simple and executable, we read it from a local file. buf, err := io.readall(f) if err != nil { panic(err) } // convert []byte into a reader. the s3 client should give us a reader // that we can use directly in the place of the filereader. try the best // to avoid reading the response as []byte and then convert it into a reader. filereader := bytes.newreader(buf) r, err := pcapgo.newreader(filereader) if err != nil { panic(err) } source := gopacket.newpacketsource(r, layers.layertypeethernet) for packet := range source.packets() { log.printf("%v", packet) } }
os.pipe
与 github.com/google/gopacket/pcap
结合使用如果 github.com/google/gopacket/pcapgo
不支持该文件格式,而我们必须使用 github.com/google/gopacket/pcap
,解决方法是创建一个管道,并将 r
文件传递给pcap.openofflinefile
不支持该文件格式,而我们必须使用 github.com/google/gopacket/pcap
,解决方法是创建一个管道,并将 r
文件传递给pcap.openofflinefile
:
package main import ( "bytes" "io" "log" "os" "github.com/google/gopacket" "github.com/google/gopacket/layers" "github.com/google/gopacket/pcap" ) func main() { f, err := os.Open("test.pcap") if err != nil { panic(err) } // As described in the question, buf is read from S3 file. In order to // make this demo simple and executable, we read it from a local file. buf, err := io.ReadAll(f) if err != nil { panic(err) } r, w, err := os.Pipe() if err != nil { panic(err) } go func() { // Convert []byte into a reader. The S3 client should give us a reader // that we can use directly in the place of the fileReader. Try the best // to avoid reading the response as []byte and then convert it into a reader. fileReader := bytes.NewReader(buf) _, err := io.Copy(w, fileReader) defer w.Close() if err != nil { panic(err) } }() handle, err := pcap.OpenOfflineFile(r) if err != nil { panic(err) } source := gopacket.NewPacketSource(handle, layers.LayerTypeEthernet) for packet := range source.Packets() { log.Printf("%v", packet) } }
注释:
github.com/google/gopacket/pcap
是 libpcap
(或 windows 上的 winpcap
或 npcap
)的包装器。这就是为什么使用 []byte
或 io.reader
有点复杂。以上是使用 s3 文件创建 gopacket 的 packetSource的详细内容。更多信息请关注PHP中文网其他相关文章!