Advertisement
yerden

Pcap to Go generator

May 24th, 2022
1,470
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. package main
  2.  
  3. import (
  4.     "bytes"
  5.     "flag"
  6.     "fmt"
  7.     "go/format"
  8.     "io"
  9.     "os"
  10.     "time"
  11.  
  12.     "github.com/google/gopacket"
  13.     "github.com/google/gopacket/pcap"
  14. )
  15.  
  16. const disclaimer = `
  17. //
  18. // This file is generated automatically. DO NOT EDIT.
  19. // Generated on %v
  20. //
  21. `
  22.  
  23. var fileName = flag.String("f", "", "Specify file name")
  24. var pkgName = flag.String("package", "main", "Specify package name")
  25. var fold = flag.Int("fold", 8, "Specify number of symbols to fold a string")
  26. var prefix = flag.String("prefix", "Frame", "Specify variable names prefix")
  27. var output = flag.String("o", "", "Specify output file")
  28.  
  29. func PrintBytes(data []byte, fold int) string {
  30.     var s string
  31.     for i := range data {
  32.         if i > 0 && i%fold == 0 {
  33.             s += "\n"
  34.         }
  35.         s += fmt.Sprintf("0x%02X,", data[i])
  36.     }
  37.     return s + "\n"
  38. }
  39.  
  40. func PrintPacket(pkt gopacket.Packet, fold int) string {
  41.     var s string
  42.     var off int
  43.     for _, layer := range pkt.Layers() {
  44.         contents := layer.LayerContents()
  45.         typ := layer.LayerType()
  46.         s += fmt.Sprintf("//\n// %v, off: %d, len: %d\n%s", typ, off,
  47.             len(contents), PrintBytes(contents, fold))
  48.         off += len(contents)
  49.     }
  50.     return s
  51. }
  52.  
  53. func FprintPacket(w io.Writer, pkt gopacket.Packet, fold int) {
  54.     var off int
  55.     fmt.Fprintf(w, "[]byte{\n")
  56.     defer fmt.Fprintf(w, "}")
  57.     for _, layer := range pkt.Layers() {
  58.         contents := layer.LayerContents()
  59.         typ := layer.LayerType()
  60.         fmt.Fprintf(w, "//\n// %v, off: %d, len: %d\n%s", typ, off,
  61.             len(contents), PrintBytes(contents, fold))
  62.         off += len(contents)
  63.     }
  64. }
  65.  
  66. const billion = 1000 * 1000 * 1000
  67.  
  68. func FprintCaptureInfo(w io.Writer, ci gopacket.CaptureInfo) {
  69.     ns := ci.Timestamp.UnixNano()
  70.     ts := ci.Timestamp.Format(time.RFC3339Nano)
  71.     fmt.Fprintf(w, `gopacket.CaptureInfo{
  72.     // %s
  73.     Timestamp: time.Unix(%d, %d),
  74.     CaptureLength: %d,
  75.     Length: %d,
  76.     }`, ts, ns/billion, ns%billion,
  77.         ci.CaptureLength, ci.Length)
  78. }
  79.  
  80. func FprintPacketSource(w io.Writer, src *gopacket.PacketSource, fold int) {
  81.     fmt.Fprintf(w, "var %s = [] struct{\nData []byte\ngopacket.CaptureInfo}{\n", *prefix)
  82.     defer fmt.Fprintf(w, "}")
  83.     n := 1
  84.     for pkt := range src.Packets() {
  85.         fmt.Fprintf(w, "//\n// Frame %d\n", n)
  86.         fmt.Fprintf(w, "{\n")
  87.         FprintPacket(w, pkt, fold)
  88.         fmt.Fprintf(w, ",\n")
  89.         FprintCaptureInfo(w, pkt.Metadata().CaptureInfo)
  90.         fmt.Fprintf(w, ",\n},\n")
  91.         n++
  92.     }
  93. }
  94.  
  95. func main() {
  96.     var err error
  97.     flag.Parse()
  98.  
  99.     f := os.Stdin
  100.     if *fileName != "" {
  101.         f, err = os.Open(*fileName)
  102.         if err != nil {
  103.             panic(err)
  104.         }
  105.         defer f.Close()
  106.     }
  107.  
  108.     out := os.Stdout
  109.     if *output != "" {
  110.         out, err = os.OpenFile(*output, os.O_TRUNC|os.O_WRONLY|os.O_CREATE, 0644)
  111.         if err != nil {
  112.             panic(err)
  113.         }
  114.         defer out.Close()
  115.     }
  116.  
  117.     handle, err := pcap.OpenOfflineFile(f)
  118.     if err != nil {
  119.         panic(err)
  120.     }
  121.     defer handle.Close()
  122.  
  123.     buf := &bytes.Buffer{}
  124.     packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
  125.     fmt.Fprintf(buf, "package %s\n\n", *pkgName)
  126.     fmt.Fprintf(buf, disclaimer, time.Now())
  127.     fmt.Fprintf(buf, "import \"time\"\n")
  128.     fmt.Fprintf(buf, "import \"github.com/google/gopacket\"\n")
  129.     FprintPacketSource(buf, packetSource, *fold)
  130.  
  131.     fmtCode, err := format.Source(buf.Bytes())
  132.     if err != nil {
  133.         panic(err)
  134.     }
  135.     fmt.Fprintf(out, string(fmtCode))
  136. }
Advertisement
RAW Paste Data Copied
Advertisement