Lorsque je reçois le fichier pcap du client s3, je dois générer la source de paquets de gopacket pour lire les paquets qu'il contient. Mais je n'ai trouvé que la fonction openofflinefile dans la documentation de gopacket, comment puis-je générer une source de paquets avec []byte (lu à partir du fichier s3).
J'ai lu le code source de la fonction openofflinefile dans gopacket, mais je suis toujours confus car je ne connais pas uintptr, puis-je générer directement un unitptr avec []byte puis l'utiliser pour générer 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
Si le package github.com/google/gopacket/pcapgo
prend en charge ce format de fichier, pensez à l'utiliser car c'est simple :
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
ensembleSi github.com/google/gopacket/pcapgo
不支持该文件格式,而我们必须使用 github.com/google/gopacket/pcap
,解决方法是创建一个管道,并将 r
文件传递给pcap.openofflinefile
le format de fichier n'est pas pris en charge et que nous devons utiliser github.com/google/gopacket/pcap
, la solution de contournement consiste à créer un tube et à transmettre le fichier 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) } }
Remarques :
github.com/google/gopacket/pcap
是 libpcap
(或 windows 上的 winpcap
或 npcap
)的包装器。这就是为什么使用 []byte
或 io.reader
C'est un peu compliqué. Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!