rscamper 0.1.0

Rust interface to CAIDA's scamper network measurement tool
Documentation
# rscamper

A safe Rust interface to [CAIDA's scamper](https://www.caida.org/catalog/software/scamper/)
network measurement tool.

`rscamper` wraps the scamper C libraries (`libscamperfile` and `libscamperctrl`) through Rust
FFI, providing idiomatic Rust types for all measurement data structures and a safe async-friendly
control loop.

## Features

- **File I/O** — read and write scamper warts/JSON files via `ScamperFile`
- **Control loop** — connect to a running scamper daemon and issue measurements via `ScamperCtrl`
- **All measurement types**`trace`, `ping`, `tracelb`, `dealias`, `host`, `http`, `tbit`,
  `sniff`, `udpprobe`, `owamp`, `sting`, `neighbourdisc`
- **Mux / VP support** — enumerate and connect to vantage points via `ScamperMux` and `ScamperVp`

## Prerequisites

`rscamper` links against `libscamperfile` and `libscamperctrl`, which are part of the scamper
distribution. Build and install scamper from source following the
[official instructions](https://www.caida.org/catalog/software/scamper/).

By default, the libraries are searched for in `/usr/local/lib` and `/usr/lib`. If you installed
scamper to a custom prefix, set the `SCAMPER_LIB_DIR` environment variable at build time:

```sh
SCAMPER_LIB_DIR=/opt/scamper/lib cargo build
```

## Installation

Add `rscamper` to your `Cargo.toml`:

```toml
[dependencies]
rscamper = "0.1"
```

## Usage

### Reading a warts file

```rust
use rscamper::{ScamperFile, ScamperObject};

let file = ScamperFile::open("results.warts", 'r', None).unwrap();
for obj in file {
    if let ScamperObject::Ping(ping) = obj {
        println!("{}", ping.to_json().unwrap_or_default());
    }
}
```

### Running a measurement via scamper daemon

```rust
use std::time::Duration;
use rscamper::{ScamperCtrl, ScamperObject};

let mut ctrl = ScamperCtrl::new(false, None).unwrap();

// Connect to a scamper daemon listening on TCP port 31337.
let inst = ctrl.add_inet(31337, None).unwrap();

ctrl.do_ping(
    &inst, "1.1.1.1",
    None, None, None, None, None, None, None, None,
    None, None, None, None, None, None, None, None,
    None, None, None, None, None,
).unwrap();
inst.done();

for item in ctrl.responses(Some(Duration::from_secs(10))) {
    if let ScamperObject::Ping(ping) = item.obj {
        if let Some(stats) = ping.stats() {
            println!("min RTT: {:?}", stats.min_rtt());
        }
    }
}
```

### Mux / vantage points

```rust
use rscamper::ScamperCtrl;

let mut ctrl = ScamperCtrl::new(false, None).unwrap();
let _mux_inst = ctrl.add_inet(31337, None).unwrap();

for vp in ctrl.vps() {
    let inst = ctrl.add_vp(&vp).unwrap();
    // issue measurements on inst ...
    inst.done();
}
```

## License

GPL-3.0-only — see the [GNU General Public License](https://www.gnu.org/licenses/gpl-3.0.html)
for details.