首頁 >後端開發 >Golang >使用 s3 檔案建立 gopacket 的 packetSource

使用 s3 檔案建立 gopacket 的 packetSource

王林
王林轉載
2024-02-05 22:42:041040瀏覽

使用 s3 文件创建 gopacket 的 packetSource

問題內容

當我從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.pipegithub.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)
    }
}

註解

  1. 這僅在 linux 上進行了測試。但它應該可以在 windows 上運行。
  2. github.com/google/gopacket/pcaplibpcap(或windows 上的winpcapnpcap)的包裝器。這就是為什麼使用 []byteio.reader 有點複雜。
  3. 當您從 s3 下載檔案時,客戶端應該為您提供一個閱讀器。您可以直接使用閱讀器(請參閱我的演示中的評論)。避免自己閱讀讀者的內容。

以上是使用 s3 檔案建立 gopacket 的 packetSource的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:stackoverflow.com。如有侵權,請聯絡admin@php.cn刪除