> ## Documentation Index
> Fetch the complete documentation index at: https://wireblast.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# PCAP replay

> Put a real capture back on the wire, at its original timing or at a rate you choose.

Sometimes the traffic you need to reproduce is traffic you already caught. Point Wireblast at a capture and it replays the frames exactly as they were recorded.

```bash theme={null}
sudo wireblast -i eno2 --pcap capture.pcap --pps 100k -d 30s
```

`--pcap` implies `--mode pcap`, so you can leave `--mode` off.

## What gets sent

Frames go out **byte for byte as captured**. Wireblast doesn't rewrite addresses, recompute checksums, or renumber anything. What you captured is what leaves the NIC.

The one exception is opt-in: give `--src-mac` or `--dst-mac` and the first 12 bytes of every frame are overwritten, so you can retarget a capture at a different next hop without editing the file.

`--packet-size` is ignored entirely. The capture decides the sizes.

## File support

Both `.pcap` and `.pcapng`, read with a pure-Go parser. No libpcap, no cgo.

The whole file is read and validated **before** anything is attached to your NIC, so a bad file fails immediately rather than halfway through a run.

| Limit          | Value       |
| -------------- | ----------- |
| Smallest frame | 14 bytes    |
| Largest frame  | 16384 bytes |
| Most packets   | 2,000,000   |

Wireblast summarises what it loaded:

```text theme={null}
capture.pcap: 300 packets, 64-1518 bytes (mean 412), spanning 2.99s
```

<Warning>
  It has to be an **Ethernet** capture. A capture taken on a tunnel, a loopback, or with a link type Wireblast can't put on a wire is refused:

  ```text theme={null}
  capture.pcap has link type Raw IP, but Wireblast can only replay Ethernet
  captures. Re-capture with an Ethernet interface, or convert the file first
  ```
</Warning>

If packets were truncated by the capture's snapshot length, you get told, because they'll go out short:

```text theme={null}
150 of 300 packets were truncated by the capture's snapshot length. They will be
replayed at their captured size, which is shorter than the original packet.
```

## Timing

Two modes, and the choice matters more than it looks.

<Tabs>
  <Tab title="rate (default)">
    Ignores the capture's timestamps and sends as fast as `--pps` and `--bps` allow. The capture becomes a source of *packet content*; you control the pace.

    ```bash theme={null}
    sudo wireblast -i eno2 --pcap capture.pcap --pps 1M -d 60s
    ```

    This is what you want for load testing with realistic packets.
  </Tab>

  <Tab title="original">
    Preserves the gaps between packets as recorded. A capture spanning 2.99 seconds takes about 2.99 seconds to replay.

    ```bash theme={null}
    sudo wireblast -i eno2 --pcap capture.pcap --pcap-timing original
    ```

    This is what you want for reproducing a scenario: a burst, a microburst, a specific interleaving.

    <Note>
      Gaps below 250µs can't be slept on accurately, so Wireblast accumulates them and pays them together. Timing stays right in aggregate; individual sub-millisecond gaps are approximate. A rate limit still applies on top, and whichever is slower wins.
    </Note>
  </Tab>
</Tabs>

Measured: a 300-packet capture spanning 2.99s replays in 3.03s with `--pcap-timing original`. Add `--pps 50` and it takes 6.7s, because the rate limit is now the slower constraint.

## Looping

`--pcap-loop` is **on by default**: the capture repeats until `--duration` expires. That's what makes a short capture useful as a traffic source.

With looping on, every queue replays the whole capture independently, so throughput scales with queue count.

Turn it off to send the capture exactly once:

```bash theme={null}
sudo wireblast -i eno2 --pcap capture.pcap --pcap-loop=false --pcap-timing original
```

<Note>
  A one-pass replay runs on **queue 0 only**, so packets go out in capture order. That's the point: order is what you're preserving. It costs you the parallelism, which is the right trade when replaying a specific scenario.

  The run ends when the capture is exhausted, whatever `--duration` says.
</Note>

## Receiving replayed traffic

`--rx-mode generated-flow` can't work here, because there are no generated flows to infer a return filter from:

```text theme={null}
--rx-mode generated-flow needs generated IP traffic; it cannot infer a return
filter for --mode pcap. Use --rx-mode udp-port, tcp-port or cidr instead
```

Use an explicit filter that matches what's in the capture.

## Trimming a big capture

If a file is over the two-million-packet limit, Wireblast tells you how to cut it down:

```text theme={null}
capture.pcap holds more than 2000000 packets, which is more than Wireblast will
load into memory. Trim it with `editcap -c 2000000`
```

`editcap` ships with Wireshark. Since looping is on by default, a few thousand representative packets usually beats a giant file anyway.

## A ready-made example

The [examples directory](https://github.com/atoonk/wireblast/tree/main/examples) ships a small `sample.pcap` and two runnable scripts: [015-pcap-replay](https://github.com/atoonk/wireblast/tree/main/examples/015-pcap-replay) for rate-paced replay, and [016-pcap-original-timing](https://github.com/atoonk/wireblast/tree/main/examples/016-pcap-original-timing) for the recorded timing.
