A small Rust learning project for experimenting with layer-2 (Ethernet) networking and ARP on Linux using the pnet crate. It discovers hosts on the local subnet and continuously broadcasts forged ARP replies (gratuitous ARP) to poison their caches, with the send thread pinned to a specific CPU core.
⚠️ Authorized use only. This is an ARP cache-poisoning tool: it forges ARP replies that impersonate the gateway (and other hosts) to redirect traffic on the LAN. Only run it on networks you own or are explicitly authorized to test. Doing this on networks you don't control is almost certainly illegal and will disrupt other devices.
- Host discovery — shells out to
nmap -sn <gateway>/24(the-ggateway,/24) to enumerate live hosts on the subnet, then drops the gateway itself, this machine's own IP, and any-w/--whitelistaddresses from the target list. Exits if nothing is left. - Interface selection — picks the first active, non-loopback interface that has a MAC and an IPv4 address, and reads its source IP/MAC (cached in
LazyLockstatics). - CPU pinning — spawns a sender thread and pins it to the core given by
-t(default1) viasched_setaffinity; the main thread prints a progress indicator while it runs. - Poison loop — the sender thread busy-waits (
_mm_pause) and, every--sleepmilliseconds, sweeps the target list. For each host it broadcasts two forged ARP replies — one aimed at the victim and one aimed at the gateway — binding the attacker's MAC to those IPs (bidirectional cache poisoning). With--no-sleepthe interval is ignored and the sweep fires on every iteration (continuous flood).
- Linux (uses
libcCPU-affinity syscalls and raw layer-2 sockets) - x86_64 CPU (uses the
_mm_pauseintrinsic in the spin loop) - Rust toolchain with edition 2024 support
nmapavailable onPATH(used for host discovery)- Elevated privileges (
CAP_NET_RAW/ root) to open a raw datalink channel
cargo build --releaseRaw socket access typically needs root:
sudo ./target/release/pulsar-star| Flag | Description | Default |
|---|---|---|
-s, --sleep <ms> |
Milliseconds between each full sweep of the target list | 1000 |
-g, --gateway <ip> |
Gateway IP — also sets the /24 subnet scanned and is excluded as a target |
192.168.1.1 |
-t, --thread <num> |
CPU core the sender thread is pinned to | 1 |
-w, --whitelist <ip> [ip ...] |
One or more IPs to exclude from the target list | (none) |
--no-sleep |
No time to wait for each full sweep (overflooding) | false |
Example:
sudo ./target/release/pulsar-star -s 1000 -g 192.168.0.1 -t 1 -w 192.168.0.50 192.168.0.51.
├── Cargo.toml # package metadata, dependencies, release profile (thin LTO)
├── src/
│ └── main.rs # entry point + all logic
└── README.md
pnet(with thepcapfeature) — datalink channels and packet buildingclap/clap_derive— command-line argument parsinglibc— CPU affinity syscalls
Early-stage / experimental personal project.