diff --git a/cmd/tools/pcaplayer/main.go b/cmd/tools/pcaplayer/main.go index 04139a33bc4da43765a904f6fcd82e767bdc0448..e8af8575dba4e46b3c99b99ebbc994c9f6925f10 100644 --- a/cmd/tools/pcaplayer/main.go +++ b/cmd/tools/pcaplayer/main.go @@ -1,4 +1,4 @@ -// This tool allows to replay recorded pcaps to a particular network interface. +// This tool allows to replay recorded packets to a TCP or UDP connection // Its aim is to debug obfsvpn server by sending particular network traffic // to it in a reproducible way. // Under the assumption of being server replies, recorded packets are filtered out @@ -20,45 +20,30 @@ import ( "github.com/google/gopacket/pcap" ) -// setup command line flags. var ( pcapFile string = "captured.pcap" host string = "127.0.0.1" port int = 443 fast bool = false quiet bool = false + n int = 1 ) func main() { - flags := flag.NewFlagSet(os.Args[0], flag.ContinueOnError) flags.StringVar(&pcapFile, "pcap", pcapFile, "path to pcap file") flags.BoolVar(&fast, "fast", fast, "send packets immediately") flags.BoolVar(&quiet, "quiet", quiet, "suppress logging skipped packets") flags.StringVar(&host, "h", host, "filter pcap file for host destination IP") flags.IntVar(&port, "p", port, "filter pcap file for host destination port") + flags.IntVar(&n, "n", n, "number of iterations the recorded packets should be sent") err := flags.Parse(os.Args[1:]) if err != nil { log.Fatalf("error parsing flags: %v", err) } - log.Printf("expecting server under test to run at %s:%d", host, port) - - // Open the pcap file - file, err := os.Open(pcapFile) - if err != nil { - log.Fatal(err) - } - defer file.Close() - - // Open the pcap handle for reading - handle, err := pcap.OpenOffline(file.Name()) - if err != nil { - log.Fatal(err) - } - defer handle.Close() - // Try to establish a TCP and a UDP connection to the target IP and port + log.Printf("expecting server under test to run at %s:%d", host, port) targetAddress := fmt.Sprintf("%s:%d", host, port) tcpConn, err := net.Dial("tcp", targetAddress) if err != nil { @@ -80,33 +65,48 @@ func main() { log.Fatal(fmt.Errorf("failed to establish a connection to %s", targetAddress)) } - // Read packets from the pcap file - packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) - lastSendTime := time.Now() - for packet := range packetSource.Packets() { - // only process incoming packets - incomingPacket := maybeDropOutgoing(packet) - if incomingPacket != nil { - if fast { - // Write the packet immediately to the network interface + // Open the pcap file + file, err := os.Open(pcapFile) + if err != nil { + log.Fatal(err) + } + defer file.Close() + + for i := 0; i < n; i++ { + // Open the pcap handle for reading + handle, err := pcap.OpenOffline(file.Name()) + if err != nil { + log.Fatal(err) + } + defer handle.Close() + + // Read packets from the pcap file + packetSource := gopacket.NewPacketSource(handle, handle.LinkType()) + lastSendTime := time.Now() + for packet := range packetSource.Packets() { + // only process incoming packets + incomingPacket := maybeDropOutgoing(packet) + if incomingPacket != nil { + if fast { + // Write the packet immediately to the network interface + writePacket(incomingPacket, tcpConn, udpConn) + continue + } + // try to keep timing of packets sent to server close to what has been recorded + timestamp := packet.Metadata().Timestamp + timeDiff := timestamp.Sub(lastSendTime) + if timeDiff > 0 { + time.Sleep(timeDiff) + } + // Write the packet to the established TCP/UDP connection writePacket(incomingPacket, tcpConn, udpConn) - continue - } - // try to keep timing of packets sent to server close to what has been recorded - timestamp := packet.Metadata().Timestamp - timeDiff := timestamp.Sub(lastSendTime) - if timeDiff > 0 { - time.Sleep(timeDiff) + lastSendTime = timestamp } - // Write the packet to the established TCP/UDP connection - writePacket(incomingPacket, tcpConn, udpConn) - lastSendTime = timestamp } } } func maybeDropOutgoing(packet gopacket.Packet) gopacket.Packet { - ipLayer := packet.Layer(layers.LayerTypeIPv4) if ipLayer == nil { return nil