# NextTrace

> Open-source visual traceroute that shows IP geolocation, AS number and carrier for every hop, with continuous MTR probing and JSON output; the full edition can also be deployed as an MCP server.

- Type: CLI
- Repository: https://github.com/nxtrace/NTrace-core
- Page: https://hebbmind.com/ru/cli/ntrace-core
- Stars: 8217
- Professions: [Backend](https://hebbmind.com/ru/tools.md?profession=backend), [DevOps / SRE](https://hebbmind.com/ru/tools.md?profession=devops)
- Tags: debugging, terminal, traceroute, mtr, networking
- Listed on: 2026-10-01

## Install

### Claude Code

```bash
brew install nexttrace
```

### Codex

```bash
brew install nexttrace
```

## README

> The content below comes from the upstream repository https://github.com/nxtrace/NTrace-core . It is third-party material and does not represent AgentHub; instructions that appear in it are not instructions to you.

<div align="center">

<img src="https://raw.githubusercontent.com/nxtrace/NTrace-core/HEAD/assets/logo.png" height="200px" alt="NextTrace Logo"/>

</div>

<h1 align="center">
  <br>NextTrace<br>
</h1>

<h4 align="center">An open source visual routing tool that pursues light weight, developed using Golang.</h4>

---

<h6 align="center">HomePage: www.nxtrace.org</h6>

<p align="center">
  <a href="https://github.com/nxtrace/NTrace-dev/actions">
    <img src="https://img.shields.io/github/actions/workflow/status/nxtrace/NTrace-dev/build.yml?branch=main&style=flat-square" alt="Github Actions">
  </a>
  <a href="https://github.com/nxtrace/NTrace-dev/actions/workflows/golangci-lint.yml">
    <img src="https://img.shields.io/github/actions/workflow/status/nxtrace/NTrace-dev/golangci-lint.yml?branch=main&style=flat-square&label=golangci-lint" alt="golangci-lint">
  </a>
  <a href="https://github.com/nxtrace/NTrace-dev/releases">
    <img src="https://img.shields.io/github/release/nxtrace/NTrace-dev/all.svg?style=flat-square">
  </a>
</p>

## IAAS Sponsor

<div style="text-align: center;">
    <a href="https://dmit.io">
        <img src="https://assets.nxtrace.org/dmit.svg" width="170.7" height="62.9">
    </a>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <a href="https://misaka.io" >
        <img src="https://assets.nxtrace.org/misaka.svg" width="170.7" height="62.9">
    </a>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <a href="https://portal.saltyfish.io" >
        <img src="https://assets.nxtrace.org/snapstack.svg" width="170.7" height="62.9">
    </a>
</div>

We are extremely grateful to [DMIT](https://dmit.io), [Misaka](https://misaka.io) and [SnapStack](https://portal.saltyfish.io) for providing the network infrastructure that powers this project.

## Default-mode migration: no earlier than 2027

> **Downstream developers:** NextTrace will switch the default operating and display mode of `nexttrace` and `nexttrace-tiny` to MTR **no earlier than 2027**. Using `--raw` alone will switch to MTR RAW at the same time. Traditional traceroute and its RAW output will remain available through `-k/--traceroute`. Programs relying on today's behavior should adopt `--traceroute` or `--traceroute --raw` now. **This release does not change the default; the switching release will be announced separately.** `ntr` remains MTR-only.

## How To Use

Document Language: English | [简体中文](https://github.com/nxtrace/NTrace-core/blob/HEAD/README_zh_CN.md)

⚠️ Please note: We welcome PR submissions from the community, but please submit your PRs to the [NTrace-dev](https://github.com/nxtrace/NTrace-dev) repository instead of [NTrace-core](https://github.com/nxtrace/NTrace-core) repository.<br>
Regarding the NTrace-dev and NTrace-core repositories:<br>
Both will largely remain consistent with each other. All development work is done within the NTrace-dev repository. The NTrace-dev repository releases new versions first. After running stably for an undetermined period, we will synchronize that version to NTrace-core. This means that the NTrace-dev repository serves as a "beta" or "testing" version.<br>
Please note, there are exceptions to this synchronization. If a version of NTrace-dev encounters a serious bug, NTrace-core will skip that flawed version and synchronize directly to the next version that resolves the issue.

### Automated Install

- Debian / Ubuntu
  - Recommended: install from the official `nexttrace-debs` APT repository
    - Supports: `amd64`, `i386`, `arm64`, `armel`, `armhf`, `loong64`, `mipsel`, `mips64el`, `ppc64el`, `riscv64`, `s390x`
    - Add the repository and install the default package:
      ```shell
      sudo install -d -m 0755 /etc/apt/keyrings
      curl -fsSL -o /tmp/nexttrace-archive-keyring.gpg https://github.com/nxtrace/nexttrace-debs/releases/latest/download/nexttrace-archive-keyring.gpg
      sudo install -m 0644 /tmp/nexttrace-archive-keyring.gpg /etc/apt/keyrings/nexttrace.gpg
      rm -f /tmp/nexttrace-archive-keyring.gpg
      printf '%s\n' 'Types: deb' 'URIs: https://github.com/nxtrace/nexttrace-debs/releases/latest/download/' 'Suites: ./' 'Signed-By: /etc/apt/keyrings/nexttrace.gpg' | sudo tee /etc/apt/sources.list.d/nexttrace.sources >/dev/null
      sudo apt update
      sudo apt install nexttrace
      ```
    - Optionally install additional flavors:
      ```shell
      sudo apt install nexttrace-tiny
      sudo apt install ntr
      ```
    - Packages can be installed side by side. Commands: `nexttrace`, `nexttrace-tiny`, `ntr`

- Linux / macOS / BSD
  - One-click installation script (Full, default)

    ```shell
    curl -sL https://nxtrace.org/nt | bash
    ```

  - One-click installation script (Tiny)

    ```shell
    curl -sL https://nxtrace.org/nt | bash -s -- --flavor tiny
    ```

  - One-click installation script (NTR)

    ```shell
    curl -sL https://nxtrace.org/nt | bash -s -- --flavor ntr
    ```

  - Installed command names: Full `nexttrace`, Tiny `nexttrace-tiny`, NTR `ntr`

  - Arch Linux AUR installation command
    - Directly download bin package (only supports amd64)
      ```shell
      yay -S nexttrace-bin
      ```
    - Build from source (only supports amd64)
      ```shell
      yay -S nexttrace
      ```
    - The AUR builds are maintained by ouuan, huyz

  - Linuxbrew's installation command

    Same as the macOS Homebrew installation method. The homebrew-core formula provides the Full flavor (`nexttrace`); the `nxtrace/nexttrace` tap provides all three flavors.

  - deepin installation command
    ```shell
    apt install nexttrace
    ```
  - [x-cmd](https://www.x-cmd.com/pkg/nexttrace) installation command

    ```shell
    x env use nexttrace
    ```

  - Termux installation command
    ```shell
    pkg install root-repo
    pkg install nexttrace
    ```
  - ImmortalWrt installation command
    ```shell
    opkg install nexttrace
    ```

- macOS
  - macOS Homebrew's installation command
    - Homebrew-core version
      ```shell
      brew install nexttrace
      ```
    - `nxtrace/nexttrace` tap version (periodically synced from the latest NTrace-core release)
      ```shell
      brew tap nxtrace/nexttrace
      brew install nxtrace/nexttrace/nexttrace
      brew install nxtrace/nexttrace/nexttrace-tiny
      brew install nxtrace/nexttrace/ntr
      ```
    - The homebrew-core build is maintained by chenrui333, please note that this version's updates may lag behind the repository Action automatically version

- Windows
  - Windows WinGet installation command
    - WinGet version
      ```powershell
      winget install nexttrace
      ```
    - WinGet build maintained by Dragon1573

  - Windows Scoop installation command
    - Scoop-extras version
      ```powershell
      scoop bucket add extras && scoop install extras/nexttrace
      ```
    - Scoop-extra is maintained by soenggam

Please note:

- The `nexttrace-debs` APT repository is maintained by nxtrace and wcbing.
- Other package sources above are maintained by open-source enthusiasts. Availability and timely updates are not guaranteed. If you encounter problems, please contact the repository maintainer to solve them, or use the binary packages provided by the official build of this project.

### Manual Install

- Download the precompiled executable

  For users not covered by the above methods, please go directly to [Release](https://www.nxtrace.org/downloads) to download the compiled binary executable.
  - `Release` provides compiled binary executables for many systems and different architectures. If none are available, you can compile it yourself.
  - Some essential dependencies of this project are not fully implemented on `Windows` by `Golang`, so currently, `NextTrace` is in an experimental support phase on the `Windows` platform.

### Build Variants

Starting from this release, NextTrace is published in **three flavors** under the same tag. Choose the one that best fits your use case:

| Feature               | `nexttrace` (Full) | `nexttrace-tiny` |    `ntr`     |
| --------------------- | :----------------: | :--------------: | :----------: |
| Normal traceroute     |         ✅         |        ✅        |      —       |
| Environment check (`--doctor`) | ✅ | ✅ | ✅ |
| Standalone MTU (`--mtu`) |      ✅         |        ✅        |      —       |
| DNS client (`-l` / `--dns`) |     ✅       |        —         |      —       |
| CDN Speed (`--speed`) |         ✅         |        —         |      —       |
| IP annotation (`--nali`) |       ✅       |        —         |      —       |
| MTR TUI               |         ✅         |        ✅         | ✅ (default) |
| MTR report (`-r`)     |         ✅         |        ✅         |      ✅      |
| MTR wide (`-w`)       |         ✅         |        ✅         |      ✅      |
| MTR raw (`--raw`)     |         ✅         |        ✅         |      ✅      |
| MTR JSON / NDJSON | ✅ | ✅ | ✅ |
| MTR custom columns (`--mtr-columns`) | ✅ | ✅ | ✅ |
| MTR recording / replay (`--mtr-record` / `--mtr-replay`) | ✅ | ✅ | ✅ |
| Linux policy routing (`--fwmark`, local probes only) | ✅ | ✅ | ✅ |
| Globalping (`--from`) |         ✅         |        —         |      —       |
| WebUI (`--deploy`) / MCP (`--deploy --mcp`) |        ✅         |        —         |      —       |
| Fast Trace (`-F`)     |         ✅         |        ✅        |      —       |
| Default mode          |     traceroute     |    traceroute    |   MTR TUI    |
| Binary name           |    `nexttrace`     | `nexttrace-tiny` |    `ntr`     |

> **Note:** `APT (nexttrace-debs)` and the `Homebrew tap (nxtrace/nexttrace)` provide all three flavors: **Full** (`nexttrace`), **Tiny** (`nexttrace-tiny`), and **NTR** (`ntr`). `homebrew-core`, AUR, Scoop, and other package managers currently install the **Full** (`nexttrace`) version only.

### Feature Matrix

- **`nexttrace`** — Full-featured build. Includes traceroute, the standalone DNS client and MTU modes, CDN speed test, IP annotation, MTR, Globalping, Fast Trace, WebUI, and deploy MCP.
- **`nexttrace-tiny`** — Lightweight build. Keeps normal traceroute, standalone MTU, and Fast Trace. Includes optional MTR TUI, reports, and RAW. No DNS client / CDN speed test / IP annotation / Globalping / WebUI / MCP. Suitable for embedded or minimal environments.
- **`ntr`** — MTR-focused build. Runs MTR TUI by default. No normal traceroute mode, standalone DNS client or `--mtu`, CDN speed test, IP annotation, Globalping, Fast Trace, WebUI, or MCP.

### Manual Build

Build from source with Go 1.27.1+ installed. Release-equivalent builds use
`GOEXPERIMENT=nojsonv2`; the Go 1.27 default JSON runtime remains covered by CI,
but its WebSocket encoding cost does not meet the release performance threshold.
See the [JSON runtime ADR](https://github.com/nxtrace/NTrace-core/blob/HEAD/docs/adr/0001-go127-json-runtime.md).

```bash
export GOTOOLCHAIN=go1.27.1
export GOEXPERIMENT=nojsonv2

# Full (all features)
go build -trimpath -o dist/nexttrace -ldflags "-w -s" .

# Tiny (optional MTR; no DNS client, no Globalping, no WebUI)
go build -tags flavor_tiny -trimpath -o dist/nexttrace-tiny -ldflags "-w -s" .

# NTR (MTR-only)
go build -tags flavor_ntr -trimpath -o dist/ntr -ldflags "-w -s" .
```

On macOS, source builds require macOS 13.0 or later, Xcode Command Line Tools, and cgo because TCP/UDP packet capture links against the system `libpcap`. For a native build, `go env CGO_ENABLED` must report `1`. If it reports `0`, remove any persistent override with `go env -u CGO_ENABLED`, ensure `xcode-select -p` succeeds, and build with `CGO_ENABLED=1`.

Cross-compile example:

```bash
# Linux arm64, Tiny flavor
GOTOOLCHAIN=go1.27.1 GOEXPERIMENT=nojsonv2 \
  GOOS=linux GOARCH=arm64 CGO_ENABLED=0 \
  go build -tags flavor_tiny -trimpath -o dist/nexttrace-tiny_linux_arm64 -ldflags "-w -s" .
```

Benchmark tooling is pinned in `go.mod`; compare saved results with `go tool benchstat before.txt after.txt`.

The `tiny` and `ntr` flavors use **compile-time build tags** to exclude modules — this is not a runtime switch. You can verify with `go version -m <binary>` that `gin`, `globalping-cli`, and `github.com/natesales/q` are absent from `nexttrace-tiny` and `ntr`.

The `.cross_compile.sh` script supports building flavors:

```bash
./.cross_compile.sh all     # Build all three flavors for all platforms
./.cross_compile.sh full    # Build only nexttrace (Full)
./.cross_compile.sh tiny    # Build only nexttrace-tiny
./.cross_compile.sh ntr     # Build only ntr
```

### Release Assets Naming

Release binaries follow this naming convention:

```
{binary}_{os}_{arch}[v{arm}][.exe][_softfloat]
```

Examples:

- `nexttrace_linux_amd64`, `nexttrace-tiny_linux_amd64`, `ntr_linux_amd64`
- `nexttrace_darwin_universal`, `nexttrace-tiny_darwin_universal`, `ntr_darwin_universal`
- `nexttrace_windows_amd64.exe`, `ntr_windows_amd64.exe`

### Get Started

`NextTrace` uses the `ICMP` protocol to perform TraceRoute requests by default, which supports both `IPv4` and `IPv6`

```bash
# IPv4 ICMP Trace
nexttrace 1.0.0.1
# URL
nexttrace http://example.com:8080/index.html?q=1

# Table output (report mode): runs trace once and prints a final summary table
nexttrace --table 1.0.0.1

# Machine-readable RAW output: pipe-delimited lines
nexttrace --traceroute --raw 1.0.0.1

# JSON output: stdout is a single JSON document
nexttrace --json 1.0.0.1

# Realtime trace output to a custom file
nexttrace --output ./trace.log 1.0.0.1

# Realtime trace output to the default log file
nexttrace --output-default 1.0.0.1

# Hide stop summaries in both terminal and file output
nexttrace --no-stop-reason --output trace.log 1.1.1.1

# IPv4/IPv6 Resolve Only, and automatically select the first IP when there are multiple IPs
nexttrace --ipv4 g.co
nexttrace --ipv6 g.co

# IPv6 ICMP Trace
nexttrace 2606:4700:4700::1111

# Developer mode: set the ENV variable NEXTTRACE_DEVMODE=1 to make fatal errors panic with a stack trace
export NEXTTRACE_DEVMODE=1

# Set TTL-group interval in normal traceroute mode (default: 300ms)
nexttrace -i 300 1.1.1.1

# Disable Path Visualization With the -M parameter
nexttrace koreacentral.blob.core.windows.net
# MapTrace URL: https://api.nxtrace.org/tracemap/html/c14e439e-3250-5310-8965-42a1e3545266.html

# Disable MPLS display using the --disable-mpls / -e parameter or the NEXTTRACE_DISABLEMPLS environment variable
nexttrace --disable-mpls example.com
export NEXTTRACE_DISABLEMPLS=1
```

Normal traceroute reports why it stopped: destination reached, a terminal unreachable response (including its marker), or the configured maximum hop count. `--json` keeps the existing top-level result shape and adds optional `StopReason` with lowercase nested fields `hop`, `reason`, `responses`, and `markers`; `responses` contains human-readable descriptions while `markers` contains machine-readable codes. Classic/raw/JSON modes do not receive an extra human-readable footer. `--output` writes the same plain stop line to the log without ANSI escapes.

`--no-stop-reason` hides all `Trace Stopped: ...` summaries in both the terminal and `--output` / `--output-default` files; they remain visible by default. Available in full and tiny builds, not ntr. It applies to normal traceroute, Fast Trace, and file-based batch tracing. It does not change mode selection, probe termination, or JSON/API stop reasons, and has no effect in other modes that accept it.

When multiple normal-trace output modes are selected, precedence is `--json` > `--table` > `--classic` > `--raw` > `--output` > realtime output. If a higher-priority mode overrides an explicit `--output` or `--output-default`, NextTrace reports that choice on stderr and does not create the ignored log file.

#### Probe environment check

```sh
nexttrace --doctor example.com
nexttrace --doctor --tcp --port 443 --language en example.com
nexttrace-tiny --doctor -6 ::1
ntr --doctor --dev eth0 example.com
```

`--doctor` generates a plain-text report and exits without tracing. It separates requested settings, DNS/source selection, system route predictions, and actual local backend initialization. It does not send probe packets, read captured traffic, query GeoIP/API services, or verify target reachability. DNS/DoT queries can use the network.

All three builds support `--doctor`. Options are limited to `--ipv4`/`--ipv6`, `--tcp`/`--udp`, `--port`, `--source`, `--source-port`, `--dev`, `--tos`, `--dot-server`, `--timeout`, `--language`, `--no-color`, and Windows `--icmp-mode`, plus their listed short aliases. Use `--doctor --help` for details. The target must be a domain or IP literal; URLs and IPv6 zone suffixes are not accepted. Doctor is incompatible with other execution modes, JSON/RAW/file output, and unrelated probe options. It rejects `--fwmark`, so it cannot verify marked routing or `SO_MARK` privileges. Doctor accepts source ports `0..65535`, not the probe mode's random value `-1`.

The default is ICMP, Chinese text, and 5000 ms per network check. Multiple DNS candidates are listed; the first matching the requested family is selected without prompting. Target DoT failures do not fall back to system DNS. A failed check does not prevent independent checks from completing. The report goes to stdout; usage and output-write errors go to stderr. Reports include target/source/interface addresses, but no token or proxy credentials.

Route queries use Linux netlink, macOS routing sockets, and Windows `GetBestRoute2`. Linux IPv4 UDP instead selects its source with a raw socket `connect` without transmitting: netlink cannot query its kernel protocol 255. This exposes the source only; `--doctor` leaves the route interface and gateway unknown. Unavailable information remains unknown. macOS/Windows route predictions cannot express all protocol, port, source-policy or TOS constraints; the report states these limits. Opening a socket or capture filter does not establish actual egress, successful packet delivery, or TOS application. Network waits have deadlines; synchronous native initialization calls have no forced-cancellation guarantee.

On Windows, `--dev` selects a source address; it does not prove device binding. Every doctor WinDivert open uses `NO_INSTALL`: it does not unpack/install a driver or run `--init`. A not-yet-installed driver is reported as unverified, since ordinary tracing may install it. Socket alternatives are reported separately. The reported backend follows the build architecture; WinDivert probe paths are currently compiled for Windows amd64.

Exit codes: **0** required checks completed without failure, **1** definite check failure, **2** invalid arguments, **3** required evidence incomplete, **130/143** interrupted by SIGINT/SIGTERM. Unverified target reachability alone does not make the exit code 3.

#### Downstream migration and explicit traditional mode

`-k/--traceroute` selects traditional traceroute in full and tiny builds; it is not an alias for the `--classic` layout. It supports existing traditional output formats, Fast Trace, and file targets; the full build also supports Globalping. Combining it with `--mtr/-t`, `--report/-r`, `--wide/-w`, or standalone DNS, MTU, speed, IP annotation, or deploy mode is an error.

```bash
nexttrace --traceroute example.com
nexttrace -k example.com
nexttrace --traceroute --raw example.com
nexttrace --mtr --raw -q 10 example.com
```

| Invocation | Today | After the default switch |
|---|---|---|
| Target only | Traditional traceroute | MTR |
| `--raw` | Traditional RAW | MTR RAW |
| `--traceroute` | Traditional traceroute | Traditional traceroute |
| `--traceroute --raw` | Traditional RAW | Traditional RAW |
| `--json/--table/--classic/--output/--output-default/--route-path` | Traditional mode | Selects traditional mode automatically |

Standalone entry points, Fast Trace, file targets, and Globalping (full build only) keep their workflows; `--json` in a standalone mode still belongs to that mode. Explicit MTR continues to reject traditional-only output formats.

When `-q` is omitted, MTR TUI and `--mtr --raw` run continuously; `--report/-r` and `--wide/-w` default to 10 probes per hop, including when combined with `--raw`. Automation should set an explicit `-q`. In MTR, `-i` is the per-hop interval (default 1000ms) and `-z` is ignored. In traditional traceroute, `-q` defaults to 3 samples per hop, `-i` is the TTL-group interval (default 300ms), and `-z` is the packet interval (default 50ms).

Do not distinguish the RAW modes by successful rows alone: traditional RAW uses 12 columns for success and preserves historical 8-column timeout rows; MTR RAW uses fixed 12-column data rows in a continuous event stream. Parsers must also honor each mode's existing information headers and stderr behavior. `NEXTTRACE_UNINTERRUPTED` retains its traditional loop behavior with `--traceroute --raw`.

Bash wrappers supporting older releases can detect the capability before invoking a trace:

```bash
trace_mode=()
nexttrace_help=$(nexttrace --help)
if [[ "$nexttrace_help" == *"--traceroute"* ]]; then
  trace_mode=(--traceroute)
fi
nexttrace "${trace_mode[@]}" --raw example.com
```

Omit the new flag on older releases. Do not retry a failed trace without the flag: that could run the measurement twice.


PS: The route visualization module is an independent component, You can find its source code at [nxtrace/traceMap](https://github.com/nxtrace/traceMap).  
The routing visualization function requires the geographical coordinates of each hop. It is currently available with NextTrace API, IPInfo, and IP-API.com.

#### Mandatory Configuration Steps for `Windows` Users

- **For Normal User Mode:**  
  Only **ICMP mode** can be used, and the firewall must allow `ICMP/ICMPv6` traffic.
  ```powershell
  netsh advfirewall firewall add rule name="All ICMP v4" dir=in action=allow protocol=icmpv4:any,any
  netsh advfirewall firewall add rule name="All ICMP v6" dir=in action=allow protocol=icmpv6:any,any
  ```
- **For Administrator Mode:**  
  **TCP/UDP mode** requires `WinDivert`.  
  **ICMP mode** supports `1=Socket` and `2=WinDivert` (`0=Auto`). If running in Socket mode, the firewall must allow `ICMP/ICMPv6`.  
  On `Windows amd64`, ICMPv4 and ICMPv6 without `--tos` (or with `--tos 0`) keep using the native Socket send path. Nonzero ICMP `--tos` uses `WinDivert` to preserve the complete field and requires administrator privilege, including when `--icmp-mode 1` selects socket reception. Native Windows ICMPv4 was observed sending zero for every tested nonzero TOS value.
  `WinDivert` can be automatically configured using the `--init` parameter, which extracts the runtime to the executable directory.

#### `NextTrace` now supports quick testing, and friends who have a one-time backhaul routing test requirement can use it

```bash
# IPv4 ICMP Fast Test (Beijing + Shanghai + Guangzhou + Hangzhou) in China Telecom / Unicom / Mobile / Education Network
nexttrace --fast-trace

# You can also use TCP SYN for testing
nexttrace --fast-trace --tcp

# You can also quickly test through a customized IP/DOMAIN list file
nexttrace --file /path/to/your/iplist.txt
# CUSTOMIZED IP DOMAIN LIST FILE FORMAT
## One IP/DOMAIN per line + space + description information (optional)
## forExample:
## 106.37.67.1 BEIJING-TELECOM
## 240e:928:101:31a::1 BEIJING-TELECOM
## bj.10086.cn BEIJING-MOBILE
## 2409:8080:0:1::1
## 223.5.5.5
```

#### `NextTrace` already supports route tracing for specified Network Devices

### TOS / IPv6 Traffic Class (`-Q`, `--tos`)

`--tos` sets the complete 8-bit IPv4 TOS / IPv6 Traffic Class field, from `0` to `255`, defaulting to `0`. Compute it as `DSCP * 4 + ECN`: DSCP 46 with ECN 0 is `--tos 184`; `--tos 46` still means the raw field value 46 (DSCP 11, ECN 2). The field is part of the probe IP header; routing and priority depend on network policy.

Linux and macOS senders use native socket options or complete IP headers. On Linux, nonzero TOS selects the automatic source address using the corresponding route, including combinations with `--fwmark`. Explicit `--source` and `--dev` remain constraints, and source selection is local to each session. Route queries match the raw socket lookup and omit transport ports serialized in user space. Source-selection or TOS-configuration failures terminate probing instead of becoming MTR loss or falling back to a default field value.

Existing traceroute, MTR, Fast Trace, file-target and Web/API/MCP probe entrypoints support TOS. DNS/RDNS, GeoIP and API helper traffic do not inherit it. Standalone MTU and Globalping do not support this option. The JSON `tos` field records the requested configuration, not a packet-capture observation.

BSD and Android expose the native options but have not completed this native packet-capture acceptance; probe permissions and system restrictions still apply. The Windows WinDivert send backend is currently compiled only for amd64, so its support does not imply Windows arm64 support.

### Linux policy routing (`--fwmark`)

`--fwmark 256` or `--fwmark 0x100` sets a 32-bit socket mark on local traceroute and MTR probes. It supports ICMP/TCP/UDP over IPv4/IPv6 in all applicable builds. Configure matching Linux `ip rule` and route tables separately; NextTrace does not edit them. The same mark need not change the route when no rule selects a different path.

Automatic source selection uses the marked route. Explicit `--source` and `--dev` remain constraints; a mark does not override them. Marked sessions do not use the legacy process-wide source cache. The query includes the kernel send protocol and TOS (IPv4 UDP with IP_HDRINCL uses protocol 255), but omits TCP/UDP ports to match the native raw sockets: their kernel route lookup does not see the transport headers serialized in user space. Later policy changes and ECMP can still affect path selection.

Values range from `0` to `4294967295`; decimal and `0x` hexadecimal are accepted, without masks. Omission leaves socket marking untouched; explicit `0` sets zero and still requires permission. Linux requires `CAP_NET_ADMIN`, or `CAP_NET_RAW` on Linux 5.17 and newer. Mark initialization failure terminates probing rather than falling back to unmarked traffic.

DNS/RDNS, GeoIP and API requests do not inherit the probe mark. Human-readable and RAW output layouts are unchanged; MTR JSON/NDJSON records an explicitly supplied mark in `effective_parameters.fwmark` as a JSON number. macOS, Windows, BSD and Android reject this option. Independent modes (including doctor/MTU/DNS/speed/deploy), Globalping, Fast Trace and file targets do not support it.

On macOS and Linux, `--dev` binds the requested source interface.
On Windows, `--dev` resolves the source IP from the selected device and uses that source address for ICMP/TCP/UDP probes; it does not bind WinDivert or sockets to a real egress interface, so Windows routing may still choose a different path. The standalone `--mtu` mode follows the same source-address behavior and also uses the device name for local MTU lookup.

```bash
# Use eth0 network interface
nexttrace --dev eth0 2606:4700:4700::1111

# Use eth0 network interface's IP
# When using the network interface's IP for route tracing, note that the IP type to be traced should be the same as network interface's IP type (e.g. both IPv4)
nexttrace --source 204.98.134.56 9.9.9.9
```

#### `NextTrace` can also use `TCP` and `UDP` protocols to perform `Traceroute` requests

```bash
# TCP SYN Trace
nexttrace --tcp www.bing.com

# You can specify the port by yourself [here is 443], the default port is 80
nexttrace --tcp --port 443 2001:4860:4860::8888

# UDP Trace
nexttrace --udp 1.0.0.1

# You can specify the target port yourself [here it is 5353], the default is port 33494
nexttrace --udp --port 5353 1.0.0.1

# For TCP/UDP Trace, you can specify the source port; by default, a fixed random port is used
# (If you need to use a different random source port for each packet, please set the ENV variable NEXTTRACE_RANDOMPORT, or set the source port to -1; this also applies to MTR text, JSON and recording)
nexttrace --tcp --source-port 14514 www.bing.com
```

#### `NextTrace` also supports a standalone DNS client mode

The full `nexttrace` flavor provides a q-compatible DNS client through a NextTrace-owned adapter over the public packages of [natesales/q v0.19.12](https://github.com/natesales/q/releases/tag/v0.19.12). `-l` / `--dns` must be the first argument; everything after it uses q-style flags and positional arguments.

```bash
# Query MX records through an explicit plain DNS server
nexttrace -l example.com MX @1.1.1.1

# Query A records over DNS-over-TLS
nexttrace --dns example.com A @tls://one.one.one.one

# Query over DNS-over-HTTPS and emit JSON
nexttrace --dns example.com A @https://cloudflare-dns.com/dns-query --format=json

# Show the dedicated DNS client help
nexttrace --dns --help
```

- Transports: UDP/TCP, DoT, DoH, DoQ, ODoH, and DNSCrypt; DNS Stamp server forms are supported for plain DNS, DoT, DoH, and DNSCrypt.
- Output formats: `pretty`, `column`, `raw`, `json`, and `yaml`.
- Query features include multiple servers and RR types, reverse lookup, DNSSEC/EDNS, NSID, PTR lookups for A/AAAA answers, and recursive AXFR.
- Configuration follows q conventions for `~/.qrc`, `Q_DEFAULT_SERVER`, `NO_COLOR`, and `SSLKEYLOGFILE`.
- This mode exists only in the full `nexttrace` flavor. `nexttrace-tiny` and `ntr` do not include or register it.
- It is a standalone CLI workflow: it does not replace the DNS resolver used by traceroute, GeoIP/RDNS, WebUI, MCP, or other service paths.

#### `NextTrace` also supports standalone path-MTU discovery mode

```bash
# Tracepath-style UDP PMTU discovery with live hop output
nexttrace --mtu 1.1.1.1

# Reuse the normal GeoIP / RDNS knobs in mtu mode
nexttrace --mtu --data-provider IPInfo --language en 1.1.1.1

# JSON output keeps the standalone mtu schema and now includes hop.geo
nexttrace --mtu --json 1.1.1.1
```

- `--mtu` is an independent UDP-only mode. It does not reuse the normal traceroute engine.
- TTY output updates the current hop in place and adds color for hop state / PMTU highlights; redirected / piped output falls back to finalized line-by-line streaming without ANSI.
- `--mtu --json` prints only the standalone MTU JSON document on stdout.
- GeoIP, RDNS, `--data-provider`, `--language`, `--no-rdns`, `--always-rdns`, and `--dot-server` all apply to this mode.

#### `NextTrace` also supports standalone CDN speed testing mode

```bash
# Apple CDN backend (default)
nexttrace --speed

# Cloudflare backend
nexttrace --speed --speed-provider cloudflare

# Dedicated speed help
nexttrace --speed --help

# Machine-readable output
nexttrace --speed --json --non-interactive --no-metadata

# Pin to a specific candidate IP, or bind a source address / device
nexttrace --speed --endpoint 1.2.3.4
nexttrace --speed --source 192.0.2.10
nexttrace --speed --dev eth0
```

- `--speed` is available only in the full `nexttrace` flavor. `nexttrace-tiny` and `ntr` do not register it.
- Main `nexttrace --help` only exposes the top-level `--speed` entry. Detailed speed flags live under `nexttrace --speed --help`.
- Backends: `apple` (default) and `cloudflare`.
- Reused common flags: `--json`, `--language`, `--no-color`, `--dot-server`, `--timeout`, `--source`, `--dev`.
- Speed-specific flags: `--speed-provider`, `--max`, `--threads`, `--latency-count`, `--non-interactive`, `--endpoint`, `--no-metadata`.
- Default terminal output includes candidate endpoints, the selected endpoint, client/server metadata, idle latency, download/upload single-thread and multi-thread rounds, loaded latency, total traffic, warnings, and degraded status.
- `--json` prints exactly one JSON document to stdout.
- Exit codes: `0` = success, `2` = degraded completion, `1` = failure, `130` = interrupted.

#### `NextTrace` can annotate IP literals in text streams

```bash
# Annotate a single line
nexttrace --nali 1.1.1.1

# Annotate pipeline output
dig example.com +short | nexttrace --nali --data-provider IPInfo --language en
```

- `--nali` is available only in the full `nexttrace` flavor. `nexttrace-tiny` and `ntr` do not register it.
- It only annotates IPv4/IPv6 literals and reuses NextTrace GeoIP providers. CDN/CNAME matching, offline databases, update logic, and nali-specific paths are not bundled.
- Reused common flags: `--data-provider`, `--language`, `--dot-server`, `--timeout`, `--dn42`, `-4`, and `-6`.
- This text annotation mode is inspired by [zu1k/nali](https://github.com/zu1k/nali), which is licensed under the [MIT License](https://github.com/zu1k/nali/blob/master/LICENSE).

#### `NextTrace` also supports some advanced functions, such as ttl control, concurrent probe packet count control, mode switching, etc.

```bash
# Display 2 latency samples per hop
nexttrace --queries 2 www.hkix.net

# Allow up to 10 probe packets per hop to collect those samples
# (NextTrace stops earlier if it has already got the replies requested by --queries)
nexttrace --max-attempts 10 www.hkix.net
# or use the ENV variable NEXTTRACE_MAXATTEMPTS to persist across runs
export NEXTTRACE_MAXATTEMPTS=10

# No concurrent probe packets, only one probe packet is sent at a time
nexttrace --parallel-requests 1 www.hkix.net

# Start Trace with TTL of 5, end at TTL of 10
nexttrace --first 5 --max-hops 10 www.decix.net
# In addition, an ENV is provided to set whether to mask the destination IP and omit its hostname
export NEXTTRACE_ENABLEHIDDENDSTIP=1

# Turn off the IP reverse parsing function
nexttrace --no-rdns www.bbix.net

# Set the probe packet size to 1024 bytes (inclusive IP + probe headers)
nexttrace --psize 1024 example.com

# Randomize each probe packet size up to 1500 bytes
nexttrace --psize -1500 example.com

# Set DSCP 46 with ECN 0 (complete TOS / traffic class value 184)
nexttrace -Q 184 example.com

# Feature: print Route-Path diagram
# Route-Path diagram example:
# AS6453 Tata Communication「Singapore『Singapore』」
#  ╭╯
#  ╰AS9299 Philippine Long Distance Telephone Co.「Philippines『Metro Manila』」
#  ╭╯
#  ╰AS36776 Five9 Inc.「Philippines『Metro Manila』」
#  ╭╯
#  ╰AS37963 Aliyun「ALIDNS.COM『ALIDNS.COM』」
nexttrace --route-path www.time.com.my

# Disable color output
nexttrace --no-color 1.1.1.1
# or use ENV
export NO_COLOR=1
```

#### Advanced tuning quick guide

| Flag | What it controls | Default / starting point | When to change it |
| --- | --- | --- | --- |
| `--queries` | Samples per hop in normal traceroute; explicit probe count per hop in MTR | traceroute: `3`; MTR report/wide (including RAW): `10` when omitted; otherwise MTR TUI/raw: unlimited when omitted | Raise to `5-10` on unstable paths |
| `--max-attempts` | Hard cap on probe packets per hop | auto-sized from `--queries` | Raise on lossy links when replies arrive slowly |
| `--parallel-requests` | Total in-flight probes across TTLs | `18` | Use `1` on multipath/load-balanced paths; keep `6-18` on stable links |
| `--send-time` | Gap between packets inside one TTL group | `50ms` | Raise to `100-200ms` on rate-limited devices; ignored in MTR |
| `--ttl-time` | Gap between TTL groups in traceroute; per-hop interval in MTR | traceroute: `300ms`; MTR: `1000ms` when omitted | Lower to speed up; raise on remote/rate-limited paths |
| `--timeout` | Per-probe timeout | `1000ms` | Raise to `2000-3000ms` for intercontinental or high-loss paths |
| `--psize` | Probe packet size | Protocol/IP-family minimum | Inclusive IP + probe headers; negative values randomize each probe up to `abs(value)`; sizes above the egress/path MTU may fragment on wire |
| `-Q`, `--tos` | IP TOS / traffic class | `0` | Set the full 8-bit IP field (DSCP*4+ECN); nonzero ICMP on Windows amd64 requires `WinDivert` |

These probe knobs are CLI-only today; `nt_config.yaml` does not yet store them. If you want reusable profiles, keep them in shell aliases or small wrapper scripts.

```bash
# Conservative profile for multipath or ECMP networks
nexttrace --parallel-requests 1 --send-time 100 --ttl-time 500 --timeout 2000 example.com

# Faster profile for stable single-path networks
nexttrace --parallel-requests 18 --send-time 20 --ttl-time 150 example.com

# Lossy long-haul profile
nexttrace --queries 5 --max-attempts 10 --timeout 2500 example.com
```

#### `NextTrace` supports MTR (My Traceroute) continuous probing mode

```bash
# MTR mode: continuous probing with ICMP (default), refreshes table in real-time
nexttrace -t 1.1.1.1
# or equivalently:
nexttrace --mtr 1.1.1.1

# MTR mode with TCP SYN probing
nexttrace -t --tcp --port 443 www.bing.com

# MTR mode with UDP probing
nexttrace -t --udp 1.0.0.1

# Set per-hop probe interval (default: 1000ms in MTR; -z/--send-time is ignored in MTR mode)
nexttrace -t -i 500 1.1.1.1

# Limit the max probes per hop (default: infinite in TUI, 10 in report mode)
nexttrace -t -q 20 1.1.1.1

# Report mode: probe each hop N times then print a final summary (like mtr -r)
nexttrace -r 1.1.1.1       # = --mtr --report, 10 probes per hop by default
nexttrace -r -q 5 1.1.1.1  # 5 probes per hop

# Wide report: no host column truncation (like mtr -rw)
nexttrace -w 1.1.1.1       # = --mtr --report --wide

# Show PTR and IP together (PTR first, IP in parentheses) in MTR output
nexttrace --mtr --show-ips 1.1.1.1
nexttrace -r --show-ips 1.1.1.1
nexttrace -w --show-ips 1.1.1.1

# MTR raw stream mode (machine-friendly, one event per line)
nexttrace --mtr --raw 1.1.1.1
nexttrace -r --raw 1.1.1.1

# Combine with other options
nexttrace -t --tcp --max-hops 20 --first 3 --no-rdns 8.8.8.8
```

MTR JSON is available in all three builds:

```bash
nexttrace --mtr --json 1.1.1.1        # continuous NDJSON events
nexttrace --mtr --json -q 10 1.1.1.1  # finite NDJSON events
nexttrace -r --json -q 10 1.1.1.1     # one final JSON report
nexttrace -w --json -q 10 1.1.1.1     # identical to -r --json
ntr --json 1.1.1.1                    # continuous NDJSON events
```

JSON always includes all available metadata (FULL), ignores `-y`, and honors Geo/PTR/provider/language settings. `-r/-w --json` use the same wide collection rules. Streams run indefinitely when `-q` is omitted or nonpositive; JSON reports default to 10 probes per hop and reject explicit nonpositive counts. `--raw` and MTR `--json` are mutually exclusive. Bare `--json` in full/tiny retains traditional traceroute JSON, including after a future default-mode switch.

NDJSON emits `start`, `probe`, `path_end`, and `end` objects with consecutive `seq` values. Reports emit exactly one object, including partial statistics on interruption or failure. Diagnostics go to stderr. Exit codes: completion `0`, runtime/initialization error `1`, invalid arguments `2`, SIGINT `130`, SIGTERM `143`. Completion does not imply reachability; use `path_end`. See the [MTR JSON v1 contract and examples](https://github.com/nxtrace/NTrace-core/blob/HEAD/docs/mtr-json.md).

Save and reopen an MTR session in any build:

```sh
nexttrace --mtr --mtr-record session.jsonl 1.1.1.1
nexttrace --mtr-replay session.jsonl
nexttrace --mtr-replay session.jsonl -r --json
```

`--mtr-record` creates a new private file alongside the selected TUI, report, RAW or JSON output. It does not enable MTR by itself; full/tiny require `-t`, `-r` or `-w`, while ntr uses its default mode. Existing files are never overwritten. A recording write failure stops probing and returns an error, preserving the written prefix. Later recording start/finish errors do not replace the first session error or its stage.


> The README is long; the above is its first 40000 characters. Full content: https://github.com/nxtrace/NTrace-core
