212 lines
13 KiB
Markdown
212 lines
13 KiB
Markdown
# Technology Stack
|
|
|
|
**Project:** NetSynth v1.2 — Extended Protocol Coverage with Grouped Sound Families
|
|
**Researched:** 2026-03-26
|
|
**Scope:** Additions/changes only. Existing stack (gopacket, go-pcap, go-lame, cobra, BurntSushi/toml) is validated and unchanged.
|
|
|
|
---
|
|
|
|
## Existing Stack (Do Not Re-research)
|
|
|
|
| Technology | Version | Status |
|
|
|------------|---------|--------|
|
|
| `github.com/gopacket/gopacket` | v1.5.0 | Validated in v1.0/v1.1, unchanged |
|
|
| `github.com/packetcap/go-pcap` | v0.0.0-20251215 | Validated in v1.0/v1.1, unchanged |
|
|
| `github.com/sjzar/go-lame` | v0.0.9 | Validated in v1.0/v1.1, unchanged |
|
|
| `github.com/spf13/cobra` | v1.10.2 | Validated in v1.0/v1.1, unchanged |
|
|
| `github.com/BurntSushi/toml` | v1.6.0 | Validated in v1.1, unchanged |
|
|
| Hand-rolled additive synth + EMA | — | Validated, extend in place |
|
|
| Ordered `[]Rule` classifier | — | Validated, extend in place |
|
|
|
|
---
|
|
|
|
## New Dependencies for v1.2
|
|
|
|
**None required.**
|
|
|
|
All features for extended protocol coverage and grouped sound families can be implemented by extending existing packages in place. No new external dependencies are needed.
|
|
|
|
---
|
|
|
|
## gopacket Protocol Decoder Coverage
|
|
|
|
This is the critical research question for v1.2. The `layers` package in `gopacket/gopacket v1.5.0` is the authoritative source.
|
|
|
|
### Protocols with Native gopacket Layer Decoders
|
|
|
|
These protocols have a dedicated `LayerType` constant and `DecodeFromBytes` implementation in `github.com/gopacket/gopacket/layers`. They auto-register via UDP/TCP port dispatch — `pkt.Layer(layers.LayerTypeSIP)` just works after gopacket decodes the packet.
|
|
|
|
| Protocol | LayerType Constant | Port Auto-Registered | Notes |
|
|
|----------|-------------------|---------------------|-------|
|
|
| ICMP v4 | `LayerTypeICMPv4` | IP protocol 1 | Already used in v1.0 |
|
|
| ICMP v6 | `LayerTypeICMPv6` | IP protocol 58 | Already used in v1.0 |
|
|
| DNS | `LayerTypeDNS` | UDP/TCP 53 | Already used in v1.0 |
|
|
| DHCP v4 | `LayerTypeDHCPv4` | UDP 67, 68 | Already used in v1.0 |
|
|
| DHCP v6 | `LayerTypeDHCPv6` | UDP 546, 547 | NEW: can add DHCPv6 classification rule |
|
|
| NTP | `LayerTypeNTP` | UDP 123 | Already used in v1.0 |
|
|
| TLS | `LayerTypeTLS` | TCP 443, 636, 989-995, 5061, etc. | Can use to improve HTTPS/SMTPS/LDAPS detection |
|
|
| SIP | `LayerTypeSIP` | UDP/TCP/SCTP 5060, 5082, 5083 | NEW: native layer decoder available |
|
|
| RADIUS | `LayerTypeRADIUS` | UDP 1812 | Possible addition for network infra traffic |
|
|
| SCTP | `LayerTypeSCTP` | IP protocol 132 | Available if needed |
|
|
| GRE | `LayerTypeGRE` | IP protocol 47 | Tunnel protocol, probably skip |
|
|
| Modbus TCP | `LayerTypeModbusTCP` | TCP/UDP 502 | Industrial — niche |
|
|
|
|
Source: `github.com/gopacket/gopacket/blob/master/layers/layertypes.go` and `layers/ports.go` — confirmed via direct inspection.
|
|
|
|
### Protocols WITHOUT gopacket Layer Decoders (Port-Based Classification Only)
|
|
|
|
These protocols do NOT have a `LayerType` in gopacket. Classification must use the existing `Rule{Protocol, DstPort, Class}` mechanism — matching by transport protocol + destination port number. This is already how most of the v1.0 rules work (SSH, HTTP, HTTPS, SMTP are all port-based).
|
|
|
|
| Protocol | Standard Port(s) | Transport | Classification Approach |
|
|
|----------|-----------------|-----------|------------------------|
|
|
| FTP | 21 (control), 20 (data) | TCP | Port-based rule: `{tcp, 21, ClassFTP}` |
|
|
| IMAP | 143, 993 (TLS) | TCP | Port-based rules: `{tcp, 143}`, `{tcp, 993}` |
|
|
| POP3 | 110, 995 (TLS) | TCP | Port-based rules: `{tcp, 110}`, `{tcp, 995}` |
|
|
| SNMP | 161 (queries), 162 (traps) | UDP | Port-based rules: `{udp, 161}`, `{udp, 162}` |
|
|
| LDAP | 389, 636 (TLS) | TCP | Port-based rules: `{tcp, 389}`, `{tcp, 636}` (note: 636 already hits LayerTypeTLS) |
|
|
| RDP | 3389 | TCP | Port-based rule: `{tcp, 3389}` |
|
|
| SMB | 445 (direct), 139 (NetBIOS) | TCP | Port-based rules: `{tcp, 445}`, `{tcp, 139}` |
|
|
| mDNS | 5353 | UDP | Port-based rule: `{udp, 5353}` — gopacket uses LayerTypeDNS registered on 53, not 5353 |
|
|
| QUIC / HTTP3 | 443 | UDP | Port-based rule: `{udp, 443}` distinguishes from HTTPS/TLS on TCP 443 |
|
|
| Telnet | 23 | TCP | Port-based rule: `{tcp, 23}` |
|
|
| HTTP alt | 8080, 8443 | TCP | Can add as additional Web family rules |
|
|
|
|
**mDNS detail:** gopacket's DNS layer registers only on UDP port 53. mDNS on UDP 5353 will decode as raw UDP payload — the existing `hashBucket` fallback handles it. A `{udp, 5353, ClassMDNS}` rule is correct and sufficient for classification without needing any layer decoder.
|
|
|
|
**QUIC detail:** QUIC uses UDP port 443 (same port HTTPS uses on TCP). The existing `{tcp, 443, ClassHTTPS}` rule only fires on TCP. A `{udp, 443, ClassQUIC}` rule is unambiguous — UDP 443 is QUIC/HTTP3 traffic on modern networks. No deep packet inspection needed for classification purposes.
|
|
|
|
**SIP detail:** gopacket v1.5.0 has a native SIP decoder (`LayerTypeSIP`) registered on UDP/TCP 5060. This means `pkt.Layer(layers.LayerTypeSIP)` works after gopacket decodes the packet. However, since the existing classifier already dispatches by transport + port via the `Rule` struct, a simple `{udp, 5060, ClassSIP}` / `{tcp, 5060, ClassSIP}` rule pair is simpler and more consistent than adding a special Layer-based code path. Use port-based rules. The native SIP layer decoder is available if future features need SIP message parsing (call rates, request types), but v1.2 only needs classification.
|
|
|
|
---
|
|
|
|
## In-Place Extensions Required
|
|
|
|
### 1. classify package — New TrafficClass constants and DefaultRules
|
|
|
|
Add new `TrafficClass` constants to `classify/types.go` for each new protocol. Extend `classify/rules.go` `DefaultRules` with new ordered entries.
|
|
|
|
**Proposed new classes by family:**
|
|
|
|
```
|
|
Mail family: ClassIMAP, ClassPOP3, ClassSMTPS (SMTP over TLS = 465/587)
|
|
Web family: ClassHTTP (existing), ClassHTTPS (existing), ClassHTTP8080, ClassQUIC
|
|
Remote family: ClassSSH (existing), ClassRDP, ClassTelnet
|
|
Discovery: ClassMDNS, ClassDHCP (existing), ClassDHCPv6
|
|
File Transfer: ClassFTP
|
|
Directory: ClassLDAP
|
|
Monitoring: ClassSNMP
|
|
Messaging: ClassSIP
|
|
Infra: ClassSMB
|
|
```
|
|
|
|
The exact set is a product decision (FEATURES.md), but every entry requires only a new `TrafficClass` string constant and a `Rule{Protocol, DstPort, Class}` entry in `DefaultRules`. No code path changes needed.
|
|
|
|
**Insertion point in DefaultRules:** New rules must come before the existing catch-alls (`{tcp, 0, ClassOtherTCP}` and `{udp, 0, ClassOtherUDP}`). Ordering within the new rules does not matter since they are distinct ports.
|
|
|
|
### 2. synth package — Frequency map and group detuning
|
|
|
|
Extend `synth/config.go` `ClassFreqConfigs` with an entry for each new `TrafficClass`. No API change — it's a map addition.
|
|
|
|
**Group-based frequency allocation approach (no new code needed):**
|
|
|
|
Group related protocols into a frequency band, using slight detuning within the band for distinction. The existing `FreqConfig.BaseHz` + `FreqConfig.Harmonics` already supports this — give family members adjacent base frequencies (e.g., 5-15 Hz apart at low frequencies, 15-30 Hz at mid frequencies) with the same harmonic shape but different waveform types.
|
|
|
|
Example for Mail family:
|
|
```go
|
|
ClassSMTP: {BaseHz: 440.0, Harmonics: ...sawtooth..., Pan: -0.55} // existing
|
|
ClassIMAP: {BaseHz: 450.0, Harmonics: ...sawtooth..., Pan: 0.55} // same family, detuned +10 Hz
|
|
ClassPOP3: {BaseHz: 435.0, Harmonics: ...sawtooth..., Pan: -0.3} // same family, detuned -5 Hz
|
|
```
|
|
|
|
The `WaveformType` field already encodes "same character within group." The existing bandlimited synthesis code handles all this correctly.
|
|
|
|
**NumLayers constant:** Currently hardcoded to 14 in `synth/config.go`. Must be updated to reflect the new total class count. Alternatively, compute it dynamically from `len(ClassFreqConfigs)`. The dynamic approach is more maintainable and requires touching only `synth/config.go`.
|
|
|
|
**GainPerLayer:** Computed as `1.0 / float64(NumLayers)`. With more layers active simultaneously, individual gain drops. This is the correct behavior — prevents clipping. Verify mix levels after adding classes.
|
|
|
|
### 3. config package — --print-config output
|
|
|
|
`--print-config` currently emits commented TOML grouped by class. With protocol families, adding a `Group` field to `FreqConfig` or a separate group-to-classes mapping in `synth/config.go` allows `--print-config` to emit sections with comment headers like `# Mail family`. This is cosmetic; no behavioral change needed.
|
|
|
|
No new dependency needed. Add a `GroupName string` field to `FreqConfig` (zero value = ungrouped) or a `var ClassGroups = map[string][]TrafficClass{...}` in `synth/config.go`.
|
|
|
|
---
|
|
|
|
## What NOT to Add
|
|
|
|
| Avoid | Why | What to Do Instead |
|
|
|-------|-----|-------------------|
|
|
| Any deep packet inspection library (gopacket TLS layer for HTTPS detection) | v1.2 goal is protocol family classification by port, not payload analysis. TLS handshake parsing adds complexity for no classification benefit since port is unambiguous. | Port-based `Rule{tcp, 443, ClassHTTPS}` — already working |
|
|
| `github.com/google/gopacket` (original) | Superseded by community fork; 270 open issues, not maintained | `gopacket/gopacket v1.5.0` (already in use) |
|
|
| Any SNMP library (e.g., `gosnmp`) | v1.2 only needs to detect SNMP traffic, not decode OIDs or walk MIBs | `{udp, 161, ClassSNMP}` port rule |
|
|
| Any SIP parsing library | v1.2 only needs to detect SIP presence for sonification, not parse SIP messages, headers, or call state | `{udp, 5060, ClassSIP}` + `{tcp, 5060, ClassSIP}` port rules |
|
|
| Separate "group" abstraction layer in classify | A `Group` field on `FreqConfig` (in synth) is sufficient for --print-config display. The classifier itself doesn't need to know about groups — families emerge from frequency proximity in the audio output. | `GroupName string` in `synth.FreqConfig` |
|
|
| Dynamic port range rules (e.g., "all TCP 1024-65535 → ClassOtherTCP") | Existing catch-alls (`DstPort: 0`) already cover this. Current Rule struct is optimized for exact-match dispatch. | Keep existing catch-all rules |
|
|
|
|
---
|
|
|
|
## Frequency Rebalancing Scope
|
|
|
|
Current v1.1 spectrum allocation (for reference):
|
|
|
|
```
|
|
65 Hz — ICMP
|
|
110 Hz — DNS
|
|
175 Hz — HTTPS
|
|
220 Hz — HTTP
|
|
330 Hz — SSH
|
|
440 Hz — SMTP
|
|
520 Hz — NTP
|
|
600 Hz — DHCP
|
|
700 Hz — OtherTCP
|
|
780 Hz — OtherUDP
|
|
862 Hz — Unknown-1 (dissonant band)
|
|
920 Hz — Unknown-2
|
|
981 Hz — Unknown-3
|
|
1047 Hz — Unknown-4
|
|
```
|
|
|
|
Adding ~8-12 new protocol classes requires rebalancing. The 65-780 Hz "known protocol" band currently has 8 classes spread over ~715 Hz (average spacing ~90 Hz). Adding 8+ new entries will compress that to ~40-50 Hz average spacing — still audibly distinct with different waveforms.
|
|
|
|
The unknown-1-4 dissonant band (862-1047 Hz) should stay — it provides the "something unknown" sound character. The rebalancing task is purely a `synth/config.go` constant edit, not a code change.
|
|
|
|
---
|
|
|
|
## Version Compatibility (Unchanged)
|
|
|
|
| Package | Version | Compatible With | Notes |
|
|
|---------|---------|-----------------|-------|
|
|
| `gopacket/gopacket` | v1.5.0 | Go 1.24+ | New protocol rules use existing API — no compat concerns |
|
|
| All other existing packages | (unchanged) | (unchanged) | No updates needed |
|
|
|
|
---
|
|
|
|
## Confidence Assessment
|
|
|
|
| Area | Confidence | Source |
|
|
|------|------------|--------|
|
|
| gopacket LayerType SIP exists at v1.5.0 | HIGH | Direct inspection of `layers/layertypes.go` and `layers/sip.go` via GitHub |
|
|
| gopacket LayerType TLS exists at v1.5.0 | HIGH | Direct inspection of `layers/layertypes.go` and `layers/ports.go` via GitHub |
|
|
| gopacket port registrations (ports.go) | HIGH | Direct inspection of `layers/ports.go` via GitHub; explicit list of pre-registered UDP/TCP ports |
|
|
| mDNS NOT registered in gopacket layers | HIGH | Port 5353 absent from `layers/ports.go` pre-registration list; confirmed via GitHub |
|
|
| QUIC NOT registered in gopacket layers | HIGH | No `quic.go` in layers directory; no port 443 UDP registration in `layers/ports.go` |
|
|
| SNMP, LDAP, RDP, SMB, FTP, IMAP, POP3 NOT in gopacket layers | HIGH | No corresponding .go files found in layers directory |
|
|
| Port-based Rule classification sufficiency for all new protocols | HIGH | All protocols have well-known IANA port assignments; existing Rule struct handles them identically to SSH/HTTP/SMTP |
|
|
| No new external dependencies needed | HIGH | All new functionality is data additions (constants, map entries) to existing packages |
|
|
|
|
---
|
|
|
|
## Sources
|
|
|
|
- `github.com/gopacket/gopacket/blob/master/layers/layertypes.go` — LayerTypeSIP (id 133), LayerTypeTLS (id 140) confirmed
|
|
- `github.com/gopacket/gopacket/blob/master/layers/sip.go` — SIP decoder implementation confirmed
|
|
- `github.com/gopacket/gopacket/blob/master/layers/ports.go` — UDP/TCP port pre-registration list; mDNS (5353), SNMP (161/162), QUIC (UDP 443) absent; SIP (5060, 5082, 5083) present
|
|
- `github.com/gopacket/gopacket/tree/master/layers` — directory listing; no mdns.go, quic.go, snmp.go, ldap.go, smb.go, rdp.go, ftp.go, imap.go, or pop3.go files
|
|
- `pkg.go.dev/github.com/gopacket/gopacket/layers` — package index confirming layer types
|
|
- IANA port assignments — standard reference for FTP/21, IMAP/143, POP3/110, SNMP/161, LDAP/389, RDP/3389, SMB/445, mDNS/5353, SIP/5060, QUIC/UDP-443
|
|
|
|
---
|
|
|
|
*Stack research for: NetSynth v1.2 — Extended Protocol Coverage with Grouped Sound Families*
|
|
*Researched: 2026-03-26*
|