// Open and create a pcap output file func openPcap(config *Config) error { if config.pcapOut != "" { f, err := os.Create(config.pcapOut) w := pcapgo.NewWriter(f) // Write the PCAP global header w.WriteFileHeader(65536, layers.LinkTypeEthernet) // Store the file/writer handles config.pcapFile = f config.pcapWriter = w log.Printf("Logging packets to %s", config.pcapOut) return err } return nil }
// PacketsToFile writes all packets from 'in' to 'out', writing out all packets // in a valid PCAP file format. func PacketsToFile(in *PacketChan, out io.Writer) error { w := pcapgo.NewWriter(out) w.WriteFileHeader(snapLen, layers.LinkTypeEthernet) count := 0 defer in.Discard() defer func() { V(1, "wrote %d packets of %d input packets", count, len(in.C)) }() for p := range in.Receive() { if len(p.Data) > snapLen { p.Data = p.Data[:snapLen] } if err := w.WritePacket(p.CaptureInfo, p.Data); err != nil { // This can happen if our pipe is broken, and we don't want to blow stack // traces all over our users when that happens, so Error/Exit instead of // Fatal. return fmt.Errorf("error writing packet: %v", err) } count++ } return in.Err() }
func TestPCAPGoWrite(t *testing.T) { f, err := ioutil.TempFile("", "pcapgo") if err != nil { t.Fatal(err) } data := []byte{0xab, 0xcd, 0xef, 0x01, 0x02, 0x03, 0x04} ci := gopacket.CaptureInfo{ Timestamp: time.Unix(12345667, 1234567000), Length: 700, CaptureLength: len(data), } func() { defer f.Close() w := pcapgo.NewWriter(f) if err := w.WriteFileHeader(65536, layers.LinkTypeEthernet); err != nil { t.Fatal(err) } if err := w.WritePacket(ci, data); err != nil { t.Fatal(err) } }() h, err := OpenOffline(f.Name()) if err != nil { t.Fatal(err) } defer h.Close() gotData, gotCI, err := h.ReadPacketData() if err != nil { t.Fatal("could not read first packet:", err) } if !bytes.Equal(gotData, data) { t.Errorf("byte mismatch:\nwant: %v\n got: %v", data, gotData) } if !reflect.DeepEqual(ci, gotCI) { t.Errorf("CI mismatch:\nwant: %v\n got: %v", ci, gotCI) } }