Replace static EMA-smoothed drones with an evolving ambient soundscape: - ADSR envelope system with sustained (2s attack, 4s release) and bursty (30ms attack, no sustain) modes per protocol group - LFO pitch wobble and amplitude tremolo with incommensurable rates per group (Eno technique) so modulation patterns never repeat - C major pentatonic frequency tuning (just intonation) — any combination of active protocols sounds consonant - tanh soft limiter on master output prevents clipping - Sync all documentation: README, PROJECT.md, ARCHITECTURE.md, v1.2 requirements traceability Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
297 lines
11 KiB
Markdown
297 lines
11 KiB
Markdown
# NetSynth
|
|
|
|
**Turn network traffic into ambient sound.**
|
|
|
|
NetSynth captures live network traffic (or reads pcap files), classifies packets into 35 protocol families, and synthesizes an ambient MP3 soundscape where each traffic type produces a distinct harmonic drone. A ping sounds different from HTTPS noise, which sounds different from a port scan.
|
|
|
|
Run it, let it listen, press Ctrl+C, get an audio fingerprint of your network.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# Live capture on eth0 (requires root or CAP_NET_RAW)
|
|
sudo netsynth -i eth0
|
|
|
|
# Press Ctrl+C after a few seconds → saves netsynth-<timestamp>.mp3
|
|
|
|
# Sonify a pcap file (no privileges needed)
|
|
netsynth --read capture.pcap -o output.mp3
|
|
|
|
# Filter to DNS traffic only
|
|
sudo netsynth -i eth0 --filter "port 53" -o dns.mp3
|
|
|
|
# Use a custom sound config
|
|
sudo netsynth -i eth0 --config my-sounds.toml
|
|
|
|
# Print effective config as a starting template
|
|
netsynth --print-config > my-sounds.toml
|
|
```
|
|
|
|
## Installation
|
|
|
|
### Prerequisites
|
|
|
|
- Go 1.24+
|
|
- C compiler (GCC or Clang) — required for MP3 encoding (CGo)
|
|
|
|
### Build from Source
|
|
|
|
```bash
|
|
git clone https://codeberg.org/gurix/yoloyolo.git
|
|
cd yoloyolo
|
|
go build -o netsynth ./cmd/netsynth
|
|
```
|
|
|
|
For a smaller binary:
|
|
|
|
```bash
|
|
go build -ldflags="-s -w" -o netsynth ./cmd/netsynth
|
|
```
|
|
|
|
### Privileges
|
|
|
|
Live packet capture requires elevated privileges on Linux:
|
|
|
|
```bash
|
|
# Option A: run as root
|
|
sudo ./netsynth -i eth0
|
|
|
|
# Option B: grant capability (preferred)
|
|
sudo setcap cap_net_raw=eip ./netsynth
|
|
./netsynth -i eth0
|
|
```
|
|
|
|
## Usage
|
|
|
|
```
|
|
netsynth [flags]
|
|
```
|
|
|
|
| Flag | Description |
|
|
|------|-------------|
|
|
| `-i`, `--interface` | Network interface to capture on |
|
|
| `--read` | Read packets from a pcap file instead of live capture |
|
|
| `-o`, `--output` | Output MP3 file path (default: `netsynth-<timestamp>.mp3`) |
|
|
| `--filter` | BPF filter expression, tcpdump syntax (e.g. `"port 53"`) |
|
|
| `--config` | Path to a TOML config file for custom sound mappings |
|
|
| `--print-config` | Print the full effective config as commented TOML and exit |
|
|
| `--verbose` | Print per-window protocol activity to stderr |
|
|
| `--list-interfaces` | List available network interfaces and exit |
|
|
|
|
### Examples
|
|
|
|
```bash
|
|
# Capture all traffic, verbose per-window output
|
|
sudo netsynth -i wlan0 --verbose
|
|
|
|
# Only HTTPS traffic
|
|
sudo netsynth -i eth0 --filter "tcp port 443" -o https.mp3
|
|
|
|
# Sonify a Wireshark capture (output derived: capture.pcap -> capture.mp3)
|
|
netsynth --read capture.pcap
|
|
|
|
# Filter a pcap file to UDP only
|
|
netsynth --read traffic.pcap --filter "udp" -o udp-only.mp3
|
|
|
|
# Use a custom sound config
|
|
sudo netsynth -i eth0 --config ~/my-sounds.toml
|
|
|
|
# Print the full effective config (great for creating a template)
|
|
netsynth --print-config > my-sounds.toml
|
|
```
|
|
|
|
## Custom Sound Configuration
|
|
|
|
NetSynth supports TOML config files to override the default sound mappings per traffic class. You can change the frequency and waveform for any class, define your own classification rules, and inspect the effective config — all without affecting defaults you don't touch.
|
|
|
|
### Config File Discovery
|
|
|
|
NetSynth looks for config files in this order (first found wins):
|
|
|
|
1. `--config <path>` flag (error if file does not exist)
|
|
2. `./netsynth.toml` in the current working directory
|
|
3. `~/.config/netsynth/config.toml`
|
|
|
|
If no config is found, NetSynth starts silently with built-in defaults.
|
|
|
|
### Config File Format
|
|
|
|
```toml
|
|
# Override sound settings per traffic class.
|
|
# Only the fields you set are changed — everything else keeps its default.
|
|
|
|
[sounds.ICMP]
|
|
frequency = 80.0 # Hz (default: 65.4)
|
|
waveform = "triangle" # sine, square, sawtooth, or triangle
|
|
|
|
[sounds.HTTPS]
|
|
frequency = 200.0
|
|
|
|
[sounds.DNS]
|
|
waveform = "square"
|
|
```
|
|
|
|
### Available Traffic Classes
|
|
|
|
35 built-in classes organized by protocol family:
|
|
|
|
| Family | Classes |
|
|
|--------|---------|
|
|
| Infrastructure | `ICMP`, `DNS`, `NTP`, `DHCP`, `mDNS`, `SSDP`, `SNMP`, `LDAP`, `Kerberos`, `Syslog` |
|
|
| Web | `HTTPS`, `HTTP`, `QUIC` |
|
|
| Mail | `SMTP`, `IMAP`, `POP3`, `SMTP-Sub` |
|
|
| Remote Access | `SSH`, `RDP`, `Telnet`, `VNC` |
|
|
| File Transfer | `FTP`, `SMB`, `TFTP` |
|
|
| Database | `MySQL`, `PostgreSQL`, `Redis`, `MongoDB` |
|
|
| Discovery | `mDNS`, `SSDP`, `SNMP` |
|
|
| VoIP | `SIP` |
|
|
| Unknown | `OtherTCP`, `OtherUDP`, `Unknown1`-`Unknown4` |
|
|
|
|
### Available Waveforms
|
|
|
|
| Waveform | Character |
|
|
|----------|-----------|
|
|
| `sine` | Pure, clean fundamental tone |
|
|
| `square` | Hollow, buzzy (odd harmonics) |
|
|
| `sawtooth` | Bright, rich (all harmonics) |
|
|
| `triangle` | Soft, mellow (odd harmonics, fast rolloff) |
|
|
|
|
All waveforms use bandlimited additive synthesis to prevent aliasing artifacts.
|
|
|
|
### Custom Classification Rules
|
|
|
|
Define your own traffic classification rules using `[[rules]]` blocks. User-defined rules fire before built-in rules (first-match-wins):
|
|
|
|
```toml
|
|
# Match internal API traffic on port 8080
|
|
[[rules]]
|
|
protocol = "tcp"
|
|
port = 8080
|
|
class = "InternalAPI"
|
|
|
|
# Match all UDP traffic (port omitted = match any)
|
|
[[rules]]
|
|
protocol = "udp"
|
|
class = "AllUDP"
|
|
|
|
# Optionally customize the sound for your custom class
|
|
[sounds.InternalAPI]
|
|
frequency = 1500.0
|
|
waveform = "sawtooth"
|
|
```
|
|
|
|
Custom classes that don't have a `[sounds.*]` entry automatically get a unique frequency in the 2500-4000 Hz range.
|
|
|
|
### Print Config
|
|
|
|
Inspect the full effective configuration (defaults merged with your overrides):
|
|
|
|
```bash
|
|
# Print defaults (useful as a starting template)
|
|
netsynth --print-config
|
|
|
|
# Print with your overrides applied
|
|
netsynth --config my-sounds.toml --print-config
|
|
|
|
# Save as a template to edit
|
|
netsynth --print-config > template.toml
|
|
```
|
|
|
|
The output includes `(default)`, `(override)`, and `(auto-assigned)` annotations so you can see what's customized. Classes are grouped by protocol family with section headers.
|
|
|
|
### Group Reassignment
|
|
|
|
You can reassign protocols to different sound families using the `[groups]` table:
|
|
|
|
```toml
|
|
[groups]
|
|
DNS = "Web" # Move DNS from Infrastructure to Web family
|
|
SIP = "Infrastructure" # Move SIP from VoIP to Infrastructure
|
|
```
|
|
|
|
Reassigned protocols inherit the waveform character of their new family in `--print-config` output.
|
|
|
|
### Validation
|
|
|
|
- **Unknown keys** are rejected at startup with an error naming the bad key (catches typos like `frequncy`)
|
|
- **Unknown class names** produce a warning but do not prevent startup
|
|
- **Invalid waveform values** are rejected with a clear error
|
|
|
|
## How It Works
|
|
|
|
NetSynth processes traffic through a four-stage pipeline:
|
|
|
|
```
|
|
Capture -> Classify -> Aggregate -> Synthesize -> MP3
|
|
```
|
|
|
|
1. **Capture** — Packets are read from a live interface (via [go-pcap](https://github.com/packetcap/go-pcap)) or a pcap file. Optional BPF filtering reduces the stream to traffic of interest.
|
|
|
|
2. **Classify** — Each packet is matched against 35 built-in protocol rules across 9 families (Infrastructure, Web, Mail, Remote Access, File Transfer, Database, Discovery, VoIP) plus any user-defined rules from the config file. User rules fire first. Unrecognized traffic is deterministically hash-bucketed into 4 "unknown" classes so it still produces distinct sounds.
|
|
|
|
3. **Aggregate** — Classified packets are grouped into 500ms time windows. Each window records per-protocol packet counts that drive synthesis amplitudes.
|
|
|
|
4. **Synthesize & Encode** — Each traffic class maps to an oscillator with ADSR envelope shaping, LFO modulation, and stereo positioning. Sustained protocols (HTTPS, SSH) fade in/out over seconds; bursty protocols (DNS, ICMP) produce short percussive accents. All layers are soft-limited and encoded to MP3 via [LAME](https://github.com/sjzar/go-lame).
|
|
|
|
### Sound Design
|
|
|
|
Protocols are grouped into families that share a waveform type and frequency register, making related traffic sound cohesive while remaining distinguishable. Frequencies are tuned to a **C major pentatonic scale** (just intonation) so that any combination of simultaneously active protocols sounds harmonically consonant.
|
|
|
|
| Family | Waveform | Frequency Range | Protocols |
|
|
|--------|----------|----------------|-----------|
|
|
| Infrastructure | Triangle | 65-147 Hz (C2-D3) | ICMP, NTP, DHCP, mDNS, SSDP, SNMP, DNS |
|
|
| Web | Sawtooth | 164-218 Hz (E3-A3) | HTTPS, HTTP, QUIC |
|
|
| Mail | Triangle | 262-392 Hz (C4-G4) | SMTP, IMAP, POP3, SMTP-Sub |
|
|
| Remote Access | Square | 436-654 Hz (A4-E5) | SSH, RDP, Telnet, VNC |
|
|
| File Transfer | Square | 784-1047 Hz (G5-C6) | FTP, SMB, TFTP |
|
|
| Unknown | Custom | 1175-2349 Hz (D6-D7) | Unknown1-4, OtherTCP, OtherUDP |
|
|
| Database | Sawtooth | 2616-4186 Hz (E7-C8) | MySQL, PostgreSQL, Redis, MongoDB |
|
|
| VoIP | Sine | 4704 Hz (D8) | SIP |
|
|
| Infrastructure (ext.) | Triangle | 5232-6534 Hz | LDAP, Kerberos, Syslog |
|
|
|
|
#### Synthesis Features
|
|
|
|
- **ADSR envelopes** — Sustained protocols (HTTPS, SSH, streaming) fade in over 2 seconds and release over 4 seconds, creating ambient pads. Bursty protocols (DNS, ICMP, NTP) have a fast 30ms attack with no sustain, producing percussive pluck-like accents on each burst.
|
|
- **LFO modulation** — Each protocol group has unique, incommensurable pitch and tremolo LFO rates (Eno technique). Pitch wobbles by a few cents; amplitude pulses gently. The combined modulation pattern never repeats, keeping the soundscape evolving.
|
|
- **Soft limiter** — A tanh-based soft limiter on the master output prevents harsh clipping during traffic spikes while preserving dynamic range.
|
|
- **Bandlimited additive synthesis** — All waveforms (sine, square, sawtooth, triangle) use harmonics below Nyquist to prevent aliasing.
|
|
- **Constant-power stereo panning** — Bass frequencies center, mid-range spreads, higher frequencies pan wider.
|
|
|
|
The result is an evolving ambient soundscape — not static drones. A typical browsing session produces warm, breathing HTTPS pads with percussive DNS plucks on page loads and gentle ICMP pulses as a periodic heartbeat. All frequencies, waveforms, and group assignments can be overridden via the [config file](#custom-sound-configuration).
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
cmd/netsynth/ CLI entry point (Cobra)
|
|
capture/ Packet capture, BPF validation, pcap file reading
|
|
classify/ Protocol classification rules and types
|
|
aggregate/ Time-window aggregation and summary output
|
|
synth/ Oscillators, waveforms, ADSR envelopes, LFO modulation, stereo mixer, tone bank
|
|
config/ TOML config loading, validation, and partial merge
|
|
encode/ MP3 encoding via embedded LAME
|
|
```
|
|
|
|
## Dependencies
|
|
|
|
| Library | Purpose |
|
|
|---------|---------|
|
|
| [gopacket/gopacket](https://github.com/gopacket/gopacket) | Packet decoding |
|
|
| [packetcap/go-pcap](https://github.com/packetcap/go-pcap) | Pure Go live capture (no libpcap) |
|
|
| [sjzar/go-lame](https://github.com/sjzar/go-lame) | MP3 encoding (embedded LAME C source) |
|
|
| [spf13/cobra](https://github.com/spf13/cobra) | CLI framework |
|
|
| [BurntSushi/toml](https://github.com/BurntSushi/toml) | TOML config parsing |
|
|
|
|
No runtime dependencies beyond the compiled binary. CGo is required at build time only (for LAME).
|
|
|
|
## Testing
|
|
|
|
```bash
|
|
go test ./... -v
|
|
```
|
|
|
|
All tests run without root privileges (capture tests use mock data and programmatically generated pcap files).
|
|
|
|
## License
|
|
|
|
See [LICENSE](LICENSE) for details.
|