Maison  >  Article  >  développement back-end  >  Créer le packetSource de gopacket à l'aide de fichiers s3

Créer le packetSource de gopacket à l'aide de fichiers s3

王林
王林avant
2024-02-05 22:42:041003parcourir

使用 s3 文件创建 gopacket 的 packetSource

Contenu de la question

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
}

Bonne réponse


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

Utilisez os.pipegithub.com/google/gopacket/pcapensemble

Si 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 :

  1. Ceci a été testé sous Linux uniquement. Mais cela devrait fonctionner sous Windows.
  2. github.com/google/gopacket/pcaplibpcap(或 windows 上的 winpcapnpcap)的包装器。这就是为什么使用 []byteio.reader C'est un peu compliqué.
  3. Lorsque vous téléchargez un fichier depuis s3, le client doit vous fournir un lecteur. Vous pouvez utiliser le lecteur directement (voir commentaires dans ma démo). Évitez de lire vous-même le contenu du lecteur.

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer