aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/github.com/google/gopacket/examples/pcaplay/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/google/gopacket/examples/pcaplay/main.go')
-rw-r--r--vendor/github.com/google/gopacket/examples/pcaplay/main.go163
1 files changed, 163 insertions, 0 deletions
diff --git a/vendor/github.com/google/gopacket/examples/pcaplay/main.go b/vendor/github.com/google/gopacket/examples/pcaplay/main.go
new file mode 100644
index 0000000..d36d860
--- /dev/null
+++ b/vendor/github.com/google/gopacket/examples/pcaplay/main.go
@@ -0,0 +1,163 @@
+// Copyright 2012 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+// The pcaplay binary load an offline capture (pcap file) and replay
+// it on the select interface, with an emphasis on packet timing
+package main
+
+import (
+ "flag"
+ "fmt"
+ "io"
+ "log"
+ "os"
+ "strings"
+ "time"
+
+ "github.com/google/gopacket"
+ "github.com/google/gopacket/examples/util"
+ "github.com/google/gopacket/pcap"
+)
+
+var iface = flag.String("i", "eth0", "Interface to write packets to")
+var fname = flag.String("r", "", "Filename to read from")
+var fast = flag.Bool("f", false, "Send each packets as fast as possible")
+
+var lastTS time.Time
+var lastSend time.Time
+
+var start time.Time
+var bytesSent int
+
+func writePacketDelayed(handle *pcap.Handle, buf []byte, ci gopacket.CaptureInfo) {
+ if ci.CaptureLength != ci.Length {
+ // do not write truncated packets
+ return
+ }
+
+ intervalInCapture := ci.Timestamp.Sub(lastTS)
+ elapsedTime := time.Since(lastSend)
+
+ if (intervalInCapture > elapsedTime) && !lastSend.IsZero() {
+ time.Sleep(intervalInCapture - elapsedTime)
+ }
+
+ lastSend = time.Now()
+ writePacket(handle, buf)
+ lastTS = ci.Timestamp
+}
+
+func writePacket(handle *pcap.Handle, buf []byte) error {
+ if err := handle.WritePacketData(buf); err != nil {
+ log.Printf("Failed to send packet: %s\n", err)
+ return err
+ }
+ return nil
+}
+
+func pcapInfo(filename string) (start time.Time, end time.Time, packets int, size int) {
+ handleRead, err := pcap.OpenOffline(*fname)
+ if err != nil {
+ log.Fatal("PCAP OpenOffline error (handle to read packet):", err)
+ }
+
+ var previousTs time.Time
+ var deltaTotal time.Duration
+
+ for {
+ data, ci, err := handleRead.ReadPacketData()
+ if err != nil && err != io.EOF {
+ log.Fatal(err)
+ } else if err == io.EOF {
+ break
+ } else {
+
+ if start.IsZero() {
+ start = ci.Timestamp
+ }
+ end = ci.Timestamp
+ packets++
+ size += len(data)
+
+ if previousTs.IsZero() {
+ previousTs = ci.Timestamp
+ } else {
+ deltaTotal += ci.Timestamp.Sub(previousTs)
+ previousTs = ci.Timestamp
+ }
+ }
+ }
+ sec := int(deltaTotal.Seconds())
+ if sec == 0 {
+ sec = 1
+ }
+ fmt.Printf("Avg packet rate %d/s\n", packets/sec)
+ return start, end, packets, size
+}
+
+func main() {
+ defer util.Run()()
+
+ // Sanity checks
+ if *fname == "" {
+ log.Fatal("Need a input file")
+ }
+
+ // Open PCAP file + handle potential BPF Filter
+ handleRead, err := pcap.OpenOffline(*fname)
+ if err != nil {
+ log.Fatal("PCAP OpenOffline error (handle to read packet):", err)
+ }
+ defer handleRead.Close()
+ if len(flag.Args()) > 0 {
+ bpffilter := strings.Join(flag.Args(), " ")
+ fmt.Fprintf(os.Stderr, "Using BPF filter %q\n", bpffilter)
+ if err = handleRead.SetBPFFilter(bpffilter); err != nil {
+ log.Fatal("BPF filter error:", err)
+ }
+ }
+ // Open up a second pcap handle for packet writes.
+ handleWrite, err := pcap.OpenLive(*iface, 65536, true, pcap.BlockForever)
+ if err != nil {
+ log.Fatal("PCAP OpenLive error (handle to write packet):", err)
+ }
+ defer handleWrite.Close()
+
+ start = time.Now()
+ pkt := 0
+ tsStart, tsEnd, packets, size := pcapInfo(*fname)
+
+ // Loop over packets and write them
+ for {
+ data, ci, err := handleRead.ReadPacketData()
+ switch {
+ case err == io.EOF:
+ fmt.Printf("\nFinished in %s", time.Since(start))
+ return
+ case err != nil:
+ log.Printf("Failed to read packet %d: %s\n", pkt, err)
+ default:
+ if *fast {
+ writePacket(handleWrite, data)
+ } else {
+ writePacketDelayed(handleWrite, data, ci)
+ }
+
+ bytesSent += len(data)
+ duration := time.Since(start)
+ pkt++
+
+ if duration > time.Second {
+ rate := bytesSent / int(duration.Seconds())
+ remainingTime := tsEnd.Sub(tsStart) - duration
+ fmt.Printf("\rrate %d kB/sec - sent %d/%d kB - %d/%d packets - remaining time %s",
+ rate/1000, bytesSent/1000, size/1000,
+ pkt, packets, remainingTime)
+ }
+ }
+ }
+
+}