Heim  >  Artikel  >  Backend-Entwicklung  >  Erstellen Sie die packetSource von gopacket mithilfe von S3-Dateien

Erstellen Sie die packetSource von gopacket mithilfe von S3-Dateien

王林
王林nach vorne
2024-02-05 22:42:041003Durchsuche

使用 s3 文件创建 gopacket 的 packetSource

Frageninhalt

Wenn ich die PCAP-Datei vom S3-Client erhalte, muss ich die Paketquelle von Gopacket generieren, um die darin enthaltenen Pakete zu lesen. Aber ich habe die Funktion openofflinefile nur in der Gopacket-Dokumentation gefunden. Wie kann ich eine Paketquelle mit []Byte generieren (aus S3-Datei lesen)?

Ich habe den Quellcode der openofflinefile-Funktion in gopacket gelesen, bin aber immer noch verwirrt, weil ich mit uintptr nicht vertraut bin. Kann ich mit []byte direkt einen Unitptr generieren und ihn dann zum Generieren einer Paketquelle verwenden?

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
}

Richtige Antwort


Versuchen Sie es github.com/google/gopacket/pcapgo

Wenn das github.com/google/gopacket/pcapgo-Paket dieses Dateiformat unterstützt, sollten Sie die Verwendung in Betracht ziehen, da es einfach ist:

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)
    }
}

Zusammen os.pipegithub.com/google/gopacket/pcapverwenden

Wenn github.com/google/gopacket/pcapgo 不支持该文件格式,而我们必须使用 github.com/google/gopacket/pcap,解决方法是创建一个管道,并将 r 文件传递​​给pcap.openofflinefile das Dateiformat nicht unterstützt wird und wir github.com/google/gopacket/pcap verwenden müssen, besteht die Problemumgehung darin, eine Pipe zu erstellen und die r-Datei zu übergeben ​An 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)
    }
}

Notizen:

  1. Dies wurde nur unter Linux getestet. Aber es sollte unter Windows funktionieren.
  2. github.com/google/gopacket/pcaplibpcap(或 windows 上的 winpcapnpcap)的包装器。这就是为什么使用 []byteio.reader Es ist etwas kompliziert.
  3. Wenn Sie eine Datei von s3 herunterladen, sollte Ihnen der Client einen Reader zur Verfügung stellen. Sie können den Reader direkt nutzen (siehe Kommentare in meiner Demo). Vermeiden Sie es, den Inhalt des Lesers selbst zu lesen.

Das obige ist der detaillierte Inhalt vonErstellen Sie die packetSource von gopacket mithilfe von S3-Dateien. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen