Network Replay

Capture and replay a TCP connection.

This library is intended to make a network replay attack or just replaying some captured network traffic as easy as possible. Currently, only TCP/IP traffic is supported.

Using this library may require root privileges or specific network capabilities when running the final compiled binary depending on what features are used.

Installation

Just add net-replay = "0.1" to your Cargo.toml.

Usage

Capture Network Traffic

Note: This module of the library is only supported on Linux.

Example of capturing all traffic destined for IP address 8.8.8.8

```rs use std::net::Ipv4Addr; use std::thread::sleep; use std::time::Duration; use std::fs::File; use std::io::BufWriter;

use netreplay::capture::{Filter, Capture}; use netreplay::ip::{IpPacket, writepcapfile};

const TARGET_IP: Ipv4Addr = Ipv4Addr::new(8, 8, 8, 8);

struct CustomFilter;

impl Filter for CustomFilter { fn filter(&mut self, packet: &IpPacket) -> bool { if packet.dest == TARGET_IP { true } else { false } } }

fn main() { // Initialize a new capture on interface 'eno1' with our custom filter that will only keep packets destined for // ip address 8.8.8.8 let cap = Capture::new(Box::new(CustomFilter), Some("eno1".into())); let caphandle = cap.start().unwrap(); // Let capture run for 5 seconds sleep(Duration::fromsecs(5)); let packets = caphandle.end().unwrap(); // Write the packets to a pcap file let pcapfile = File::create("capture.pcap").unwrap(); let mut writer = BufWriter::new(pcapfile); writepcap_file(&packets, &mut writer).unwrap(); } ```

Example of replaying some captured packets

```rs use std::net::Ipv4Addr; use std::fs::File; use std::io::BufReader; use std::net::TcpStream;

use netreplay::replay::{Arbiter, Action, Replayer}; use netreplay::ip::{IpPacket, readpcapfile, TcpFlags};

// Will be used to decide what to do for each packet in the replay // Can cause the replayer to send or read // // This arbiter will replay a connection between a host ip address of 8.8.8.8 // and a client address of 192.168.0.1 struct CustomArbiter;

impl Arbiter for CustomArbiter { fn decide(&mut self, packet: &IpPacket) -> Action { const CLIENT: Ipv4Addr = Ipv4Addr::new(192, 168, 0, 1); const HOST: Ipv4Addr = Ipv4Addr::new(8, 8, 8, 8);

if packet.source == CLIENT && packet.dest == HOST && packet.payload.flags.contains(TcpFlags::PSH) {
  return Action::Send(None);
}

if packet.source == HOST && packet.dest == CLIENT && packet.payload.flags.contains(TcpFlags::PSH) {
  return Action::Recv(None);
}
// If packet is not from the replay we want just pass
Action::Pass

}

// No internal state so don't need to udpate fn update(&mut self, _data: &[u8], _original: &[u8]) {} }

fn main() { let capture = File::open("capture.pcap").unwrap(); let mut reader = BufReader::new(capture); let packets = readpcapfile(&mut reader).unwrap(); // Replay capture to a different address let socket = TcpStream::connect("9.9.9.9:80").unwrap(); let replayer = Replayer::new(socket, packets, Box::new(CustomArbiter)); let orignalsocket = replayer.replay().unwrap(); } ```