當我從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
:
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中文網其他相關文章!