netls 1.1.0

Network connections viewer for daily use and automation - container visibility, JSON/CSV output, process tree, live watch mode
Documentation
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.1.0] - 2026-04-23

### Added

- Negation flags for every boolean option configurable via `[defaults]` or
  a profile: `--no-json`, `--no-pretty`, `--no-csv`, `--no-ipv4`,
  `--no-ipv6`, `--loopback` (antonym of `--no-loopback`), `--no-listen`,
  `--no-all`, `--no-queues`, `--no-service-names`, `--no-age`, `--no-tree`,
  `--no-systemd`, `--no-fd`, `--no-cmdline`, `--no-containers`,
  `--no-resolve-dns`, `--no-resolve-proxy`. Lets the user override a `true`
  value on the command line without editing the config. If both `--X` and
  `--no-X` appear on the same command line, the last one wins. Hidden from
  `--help` to keep it readable. Closes the "known limitation" noted in
  the 1.0.0 README.
- `--no-service-names` also disables the `[ports]` auto-enable.

## [1.0.0] - 2026-04-22

### Changed

- `Filter::proto` and `Filter::state` now take `Proto` and `State` enums
  instead of strings.
- `sort_connections` now takes a `SortKey` enum instead of a string.
- `Connection::fd_usage` changed from `Option<(usize, usize)>` to
  `Option<FdUsage>` with named `open` and `soft_limit` fields.
- Modules `tui`, `tui_common`, `watch`, `output`, `services` are no longer
  part of the library API (moved into the binary crate).
- Modules `dns`, `docker`, `platform` are now `pub(crate)`.
- `Connection::local` and `Connection::remote` now carry raw addresses
  (e.g. `[::1]:80`). The CLI still prints `localhost:80` / `*:80` via
  `compact_addr` at render time.
- `snapshot_with_containers` now returns `SnapshotResult` (connections +
  warnings) instead of `Vec<Connection>`. Docker-side failures no longer
  print to stderr from inside the library.
- `Connection::key` now returns a `ConnectionKey` newtype. Signatures of
  `diff_connections` and `resolve_proxy_origins` updated accordingly.
- `diff_connections` returns `ConnectionDiff { new, closed }` instead of
  a bare `(HashSet, Vec)` tuple.
- `resolve_proxy_origins` values are now `Vec<String>` (one entry per
  originating process) instead of a comma-joined `String`.
- `FdUsage::soft_limit` is now `Option<usize>` (`None` when the limit
  could not be read). Previously a `usize` with `usize::MAX` sentinel.
- `top_connections` returns `Vec<TopProcess>` instead of
  `Vec<(String, usize)>`. Field names: `name`, `count`.
- `Error::Parse` is now a struct-variant `{ message: String }` instead of
  a tuple variant `(String)`. Adding context fields later stays additive.
- `ConfigError::Parse` is now a struct-variant `{ path, message }` instead
  of a tuple variant `(PathBuf, String)`. Same rationale as `Error::Parse`.

### Added

- `--containers` now also enumerates containers from a running Podman
  daemon. Both the rootful (`/run/podman/podman.sock`) and rootless
  (`$XDG_RUNTIME_DIR/podman/podman.sock`) sockets are probed; results
  from Docker and Podman are merged.
- `--proto raw` lists raw IP sockets (`SOCK_RAW`), used by `CAP_NET_RAW`
  tools like `tcpdump`, routing daemons (bird, FRR), and nmap. Linux
  reads `/proc/net/raw*`; macOS surfaces `SOCK_RAW` via libproc.
- `--proto icmp` lists ICMP datagram sockets (`SOCK_DGRAM` +
  `IPPROTO_ICMP`/`IPPROTO_ICMPV6`), used by `blackbox_exporter`,
  Kubernetes probes, Go `net/icmp` monitors, and any tool that does
  unprivileged ICMP without `CAP_NET_RAW`. Linux reads `/proc/net/icmp*`;
  macOS distinguishes ICMP datagrams from UDP by inspecting `soi_protocol`
  (previously misclassified as UDP).
- `Proto::Raw`, `Proto::Icmp` variants and `Summary::raw_total`,
  `Summary::icmp_total` fields.
- `FromStr` impls for `Proto`, `State`, `SortKey`.
- `ParseEnumError` returned by those `FromStr` impls.
- `docker_proxy_service` replaces `resolve_docker_name` and returns
  just the service name.
- `Connection::new(proto, local, remote)` minimal constructor. Needed
  because `Connection` is now `#[non_exhaustive]`: external crates can
  no longer use struct-literal construction.
- `ConnectionDiff { new, closed }` struct returned by `diff_connections`.
- `TopProcess { name, count }` struct returned by `top_connections`.
- `#[non_exhaustive]` on `Connection`, `Config`, `Defaults`, `LoadedConfig`,
  `ConnectionDiff`, `TopProcess`, and the previously marked `Proto`,
  `State`, `Error`, `Summary`, `ConfigError`, `FdUsage`, `ParseEnumError`,
  `SortKey`, `SnapshotResult`.

### Removed

- `NO_PERMISSION`, `Connection::state_str`, `Connection::process_display`,
  `format_process_text` (CLI display helpers; now binary-only).

### Fixed

- Docker socket reads now have a 2s read/write timeout.
- `Connection::text_matches` now lowercases the query internally
  (previously required the caller to pre-lowercase or silently missed).
- `--resolve-dns` (`resolve_dns`) now runs lookups concurrently under a
  single 2s deadline. Previous behaviour was 2s per unique IP in serial.

## [0.2.0] - 2026-04-19

### Added

**Configuration files** (`~/.config/netls/config.toml`, `NETLS_CONFIG`, or `--config PATH`):
- `[defaults]`: defaults for any long-form CLI flag
- `[profiles.<name>]`: named overlays activated with `--profile <name>`
- `[ports]`: port to service-name overrides

**New CLI flags:**
- `--config PATH`: load a specific file
- `--profile NAME`: activate a named profile
- `--init-config`: write a starter config (refuses to overwrite without `--force`)
- `--show-config`: print the resolved effective config with origin per field

**Quality of life:**
- `[ports]` non-empty auto-enables `--service-names`
- `NETLS_CONFIG` paths starting with `~` are expanded
- When `--profile NAME` is active, prints `applied: ... from <path>` to stderr

**Library API:**
- New module `netls::config` (`Config`, `Defaults`, `LoadedConfig`, `load`)
- New public constants `netls::VALID_{STATES,PROTOS,SORT,GROUP_BY}`

### Changed

- `--service-names` now reads `/etc/services` after the curated built-in map.
  Previously only ~28 hand-picked ports were annotated; thousands of IANA
  names are now resolved automatically. Built-in entries still win ties.

## [0.1.1] - 2026-04-18

### Fixed

- Build failure on `aarch64-unknown-linux-gnu`: replaced hard-coded `[i8; 256]`
  hostname buffer in `src/dns.rs` with `[libc::c_char; 256]`. `c_char` is `i8`
  on x86_64 but `u8` on aarch64, breaking the `getnameinfo` call signature on
  ARM64 Linux.

## [0.1.0] - 2026-04-18

Initial release.

### Added

- Cross-platform connection snapshot (Linux via `/proc/net/*`, macOS via `libproc`)
- Output formats: table (default), JSON (one object per line, `--pretty` available), CSV
- Watch mode (`--watch [N]`) with live diff highlighting new/closed connections
- Interactive TUI (`--tui`)
- Filters: `--port`, `--pid`, `--process`, `--state`, `--proto`, `--ipv4`/`--ipv6`, `--no-loopback`, `--listen`, `--all`
- Aggregation: `--summary` (with `--warn-timewait`), `--top N`, `--count`, `--sort`, `--group-by`
- Snapshot/diff: `--save FILE`, `--diff FILE`
- Port utilities: `--check-port`, `--kill PORT [--force]`, `--wait-for PORT [--timeout SECS]`
- Extra columns: `--queues`, `--service-names`, `--age`, `--tree`, `--systemd`, `--fd`, `--cmdline`, `--containers`, `--resolve-dns`, `--resolve-proxy`
- Library API for programmatic access (`netls::snapshot`, `Filter`, `Connection`)