Showing preview only (1,775K chars total). Download the full file or copy to clipboard to get everything.
Repository: fujiapple852/trippy
Branch: master
Commit: e12e49159e93
Files: 257
Total size: 1.6 MB
Directory structure:
gitextract_swvmlbvf/
├── .config/
│ ├── spellcheck.toml
│ └── trippy.dic
├── .devcontainer/
│ └── devcontainer.json
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci.yml
│ ├── deploy.yml
│ └── release.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── README.md
├── RELEASES.md
├── crates/
│ ├── README.md
│ ├── trippy/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ └── main.rs
│ ├── trippy-core/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── constants.rs
│ │ │ ├── error.rs
│ │ │ ├── flows.rs
│ │ │ ├── lib.rs
│ │ │ ├── net/
│ │ │ │ ├── channel.rs
│ │ │ │ ├── common.rs
│ │ │ │ ├── extension.rs
│ │ │ │ ├── ipv4.rs
│ │ │ │ ├── ipv6.rs
│ │ │ │ ├── platform/
│ │ │ │ │ ├── byte_order.rs
│ │ │ │ │ ├── unix.rs
│ │ │ │ │ └── windows.rs
│ │ │ │ ├── platform.rs
│ │ │ │ ├── socket.rs
│ │ │ │ └── source.rs
│ │ │ ├── net.rs
│ │ │ ├── probe.rs
│ │ │ ├── state.rs
│ │ │ ├── strategy.rs
│ │ │ ├── tracer.rs
│ │ │ └── types.rs
│ │ └── tests/
│ │ ├── resources/
│ │ │ ├── simulation/
│ │ │ │ ├── ipv4_icmp.toml
│ │ │ │ ├── ipv4_icmp_gaps.toml
│ │ │ │ ├── ipv4_icmp_min.toml
│ │ │ │ ├── ipv4_icmp_ooo.toml
│ │ │ │ ├── ipv4_icmp_pattern.toml
│ │ │ │ ├── ipv4_icmp_quick.toml
│ │ │ │ ├── ipv4_icmp_tos.toml
│ │ │ │ ├── ipv4_icmp_wrap.toml
│ │ │ │ ├── ipv4_tcp_fixed_dest.toml
│ │ │ │ ├── ipv4_udp_classic_fixed_dest.toml
│ │ │ │ ├── ipv4_udp_classic_fixed_src.toml
│ │ │ │ ├── ipv4_udp_classic_privileged_tos.toml
│ │ │ │ ├── ipv4_udp_classic_unprivileged.toml
│ │ │ │ ├── ipv4_udp_classic_unprivileged_tos.toml
│ │ │ │ ├── ipv4_udp_dublin_fixed_both.toml
│ │ │ │ ├── ipv4_udp_paris_fixed_both.toml
│ │ │ │ ├── ipv6_icmp.toml
│ │ │ │ ├── ipv6_icmp_min.toml
│ │ │ │ ├── ipv6_icmp_pattern.toml
│ │ │ │ ├── ipv6_tcp_fixed_dest.toml
│ │ │ │ ├── ipv6_udp_classic_fixed_dest.toml
│ │ │ │ ├── ipv6_udp_classic_fixed_src.toml
│ │ │ │ ├── ipv6_udp_classic_unprivileged.toml
│ │ │ │ ├── ipv6_udp_classic_unprivileged_tos.toml
│ │ │ │ ├── ipv6_udp_dublin_fixed_both.toml
│ │ │ │ └── ipv6_udp_paris_fixed_both.toml
│ │ │ └── state/
│ │ │ ├── all_status.toml
│ │ │ ├── floss_bloss.toml
│ │ │ ├── full_completed.toml
│ │ │ ├── full_mixed.toml
│ │ │ ├── minimal.toml
│ │ │ ├── nat.toml
│ │ │ ├── no_latency.toml
│ │ │ ├── non_default_minimum_ttl.toml
│ │ │ └── tos.toml
│ │ └── sim/
│ │ ├── main.rs
│ │ ├── network/
│ │ │ ├── ipv4.rs
│ │ │ └── ipv6.rs
│ │ ├── network.rs
│ │ ├── simulation.rs
│ │ ├── tests.rs
│ │ ├── tracer.rs
│ │ └── tun_device.rs
│ ├── trippy-dns/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── config.rs
│ │ ├── lazy_resolver.rs
│ │ ├── lib.rs
│ │ └── resolver.rs
│ ├── trippy-packet/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── buffer.rs
│ │ ├── checksum.rs
│ │ ├── error.rs
│ │ ├── icmp_extension.rs
│ │ ├── icmpv4.rs
│ │ ├── icmpv6.rs
│ │ ├── ip.rs
│ │ ├── ipv4.rs
│ │ ├── ipv6.rs
│ │ ├── lib.rs
│ │ ├── tcp.rs
│ │ └── udp.rs
│ ├── trippy-privilege/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ └── trippy-tui/
│ ├── Cargo.toml
│ ├── build.rs
│ ├── locales.toml
│ ├── src/
│ │ ├── app.rs
│ │ ├── config/
│ │ │ ├── binding.rs
│ │ │ ├── cmd.rs
│ │ │ ├── columns.rs
│ │ │ ├── constants.rs
│ │ │ ├── file.rs
│ │ │ └── theme.rs
│ │ ├── config.rs
│ │ ├── frontend/
│ │ │ ├── binding.rs
│ │ │ ├── columns.rs
│ │ │ ├── config.rs
│ │ │ ├── render/
│ │ │ │ ├── app.rs
│ │ │ │ ├── bar.rs
│ │ │ │ ├── body.rs
│ │ │ │ ├── bsod.rs
│ │ │ │ ├── chart.rs
│ │ │ │ ├── flows.rs
│ │ │ │ ├── footer.rs
│ │ │ │ ├── header.rs
│ │ │ │ ├── help.rs
│ │ │ │ ├── histogram.rs
│ │ │ │ ├── history.rs
│ │ │ │ ├── settings.rs
│ │ │ │ ├── splash.rs
│ │ │ │ ├── table.rs
│ │ │ │ ├── tabs.rs
│ │ │ │ ├── util.rs
│ │ │ │ └── world.rs
│ │ │ ├── render.rs
│ │ │ ├── theme.rs
│ │ │ └── tui_app.rs
│ │ ├── frontend.rs
│ │ ├── geoip.rs
│ │ ├── lib.rs
│ │ ├── locale.rs
│ │ ├── print.rs
│ │ ├── report/
│ │ │ ├── csv.rs
│ │ │ ├── dot.rs
│ │ │ ├── flows.rs
│ │ │ ├── json.rs
│ │ │ ├── silent.rs
│ │ │ ├── stream.rs
│ │ │ ├── table.rs
│ │ │ └── types.rs
│ │ ├── report.rs
│ │ └── util.rs
│ └── tests/
│ └── resources/
│ └── snapshots/
│ ├── trippy_tui__config__tests__compare_snapshot@trip.snap
│ ├── trippy_tui__config__tests__compare_snapshot@trip_--help.snap
│ ├── trippy_tui__config__tests__compare_snapshot@trip_-h.snap
│ ├── trippy_tui__print__tests__output@generate_bash_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_elvish_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_fish_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_man_page.snap
│ ├── trippy_tui__print__tests__output@generate_powershell_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_zsh_shell_completions.snap
│ ├── trippy_tui__print__tests__output@tui_binding_commands_match.snap
│ └── trippy_tui__print__tests__output@tui_theme_items_match.snap
├── deny.toml
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── astro.config.mjs
│ ├── package.json
│ ├── public/
│ │ └── CNAME
│ ├── src/
│ │ ├── content/
│ │ │ ├── config.ts
│ │ │ ├── docs/
│ │ │ │ ├── 0.12.2/
│ │ │ │ │ ├── development/
│ │ │ │ │ │ └── crates.md
│ │ │ │ │ ├── guides/
│ │ │ │ │ │ ├── faq.md
│ │ │ │ │ │ ├── privileges.md
│ │ │ │ │ │ ├── recommendation.md
│ │ │ │ │ │ ├── usage.md
│ │ │ │ │ │ └── windows_firewall.md
│ │ │ │ │ ├── index.mdx
│ │ │ │ │ ├── reference/
│ │ │ │ │ │ ├── bindings.md
│ │ │ │ │ │ ├── cli.md
│ │ │ │ │ │ ├── column.md
│ │ │ │ │ │ ├── configuration.md
│ │ │ │ │ │ ├── locale.md
│ │ │ │ │ │ ├── theme.md
│ │ │ │ │ │ └── version.md
│ │ │ │ │ └── start/
│ │ │ │ │ ├── features.md
│ │ │ │ │ ├── getting-started.mdx
│ │ │ │ │ └── installation.md
│ │ │ │ ├── 0.13.0/
│ │ │ │ │ ├── development/
│ │ │ │ │ │ └── crates.md
│ │ │ │ │ ├── guides/
│ │ │ │ │ │ ├── faq.md
│ │ │ │ │ │ ├── privileges.md
│ │ │ │ │ │ ├── recommendation.md
│ │ │ │ │ │ ├── usage.md
│ │ │ │ │ │ └── windows_firewall.md
│ │ │ │ │ ├── index.mdx
│ │ │ │ │ ├── reference/
│ │ │ │ │ │ ├── bindings.md
│ │ │ │ │ │ ├── cli.md
│ │ │ │ │ │ ├── column.md
│ │ │ │ │ │ ├── configuration.md
│ │ │ │ │ │ ├── locale.md
│ │ │ │ │ │ ├── overview.mdx
│ │ │ │ │ │ ├── theme.md
│ │ │ │ │ │ └── version.md
│ │ │ │ │ └── start/
│ │ │ │ │ ├── features.md
│ │ │ │ │ ├── getting-started.mdx
│ │ │ │ │ └── installation.md
│ │ │ │ ├── development/
│ │ │ │ │ └── crates.md
│ │ │ │ ├── guides/
│ │ │ │ │ ├── docker.md
│ │ │ │ │ ├── faq.md
│ │ │ │ │ ├── privileges.md
│ │ │ │ │ ├── recommendation.md
│ │ │ │ │ ├── usage.md
│ │ │ │ │ └── windows_firewall.md
│ │ │ │ ├── index.mdx
│ │ │ │ ├── reference/
│ │ │ │ │ ├── bindings.md
│ │ │ │ │ ├── cli.md
│ │ │ │ │ ├── column.md
│ │ │ │ │ ├── configuration.md
│ │ │ │ │ ├── locale.md
│ │ │ │ │ ├── overview.mdx
│ │ │ │ │ ├── theme.md
│ │ │ │ │ └── version.md
│ │ │ │ └── start/
│ │ │ │ ├── features.md
│ │ │ │ ├── getting-started.mdx
│ │ │ │ └── installation.md
│ │ │ └── versions/
│ │ │ ├── 0.12.2.json
│ │ │ └── 0.13.0.json
│ │ ├── env.d.ts
│ │ └── styles/
│ │ └── custom.css
│ └── tsconfig.json
├── dprint.json
├── examples/
│ ├── README.md
│ ├── hello-world/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ └── toy-traceroute/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
├── snap/
│ └── snapcraft.yaml
├── trippy-config-sample.toml
└── ubuntu-ppa/
├── Dockerfile
├── README.debian
├── README.md
├── cargo.config
├── changelog
├── control
├── copyright
├── release.sh
├── rules
├── source/
│ ├── format
│ └── include-binaries
├── trippy.docs
└── trippy.install
================================================
FILE CONTENTS
================================================
================================================
FILE: .config/spellcheck.toml
================================================
dev_comments = true
skip_readme = false
[Hunspell]
lang = "en_US"
search_dirs = ["."]
extra_dictionaries = ["trippy.dic"]
skip_os_lookups = false
use_builtin = true
================================================
FILE: .config/trippy.dic
================================================
100
%
'
+
100ms
10ms
1s
300s
5s
=
>
ASN
BSD4
CSV
Cloudflare
DF
DSCP
ECMP
ECN
Endianness
FreeBSD
GeoIp
Geolocation
Graphviz
IANA
ICMPv4
ICMPv6
IPinfo
IPs
IPv4
IPv6
MaxMind
NAT'ed
Num
ROFF
RTT
TBD
TODO
TOS
TXT
Trippy
Tui
XDG
accessor
addr
addrs
asn
boolean
calc
checksum
checksums
cidr
cloneable
config
connectionless
datagram
dec
deserialization
dest
dns
dublin
endianness
enqueue
enqueued
enqueuing
frontend
geolocation
getsockname
holsravbwdt
hostname
hostnames
icmp
impl
ip
ipv6
jitter
json
localhost
lookups
macOS
mmdb
mpls
multipath
newtype
paris
rfc1889
rfc2460
rfc2474
rfc2475
rfc2476
rfc3168
rfc3246
rfc3550
rfc4443
rfc4884
rfc5865
rfc8622
src
stddev
struct
submodule
syscall
tcp
timestamp
toml
traceroute
trippy
ttl
tui
tuple
u8
udp
uninitialised
unix
unselected
================================================
FILE: .devcontainer/devcontainer.json
================================================
{
"image": "mcr.microsoft.com/devcontainers/universal:2",
"features": {
"ghcr.io/devcontainers/features/rust:1": {}
}
}
================================================
FILE: .github/FUNDING.yml
================================================
github: fujiapple852
buy_me_a_coffee: fujiapple852
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a bug report
title: ''
labels: triage
assignees: ''
---
**Describe the bug**
<!-- A description of what the bug is. -->
**To Reproduce**
<!-- A description of the steps to reproduce the behavior including the full `trip` or `trip.exe` command line. -->
**Expected behavior**
<!-- A description of what you expected to happen. -->
**Screenshots**
<!-- If applicable, add screenshots to help explain your problem. -->
**Environment Info**
- OS: <!-- e.g. Linux, Windows 11, macOS -->
- Trippy version: <!-- the output of `trip -V` -->
- Installation method: <!-- e.g. `brew`, `winget`, `cargo` -->
- Terminal / Console: <!-- If you are not sure you can use "About" or, "Help" on the terminal window to gather the requested information. e.g. `iTerm2`, `cmd.exe`, `PowerShell`, 'GNOME Terminal' -->
**Additional context**
<!-- Add any other context about the problem here. -->
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: triage
assignees: ''
---
**Describe the feature you'd like**
<!-- A clear and concise description of what you want to happen. -->
**Describe alternatives you've considered**
<!-- A clear and concise description of any alternative solutions or features you've considered. -->
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->
================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "daily"
ignore:
- dependency-name: "clap*"
update-types:
- "version-update:semver-patch"
- dependency-name: "serde*"
update-types:
- "version-update:semver-patch"
- dependency-name: "anyhow"
update-types:
- "version-update:semver-patch"
- dependency-name: "thiserror"
update-types:
- "version-update:semver-patch"
allow:
- dependency-type: "direct"
open-pull-requests-limit: 10
rebase-strategy: "disabled"
================================================
FILE: .github/workflows/ci.yml
================================================
on:
pull_request:
branches: [ master ]
schedule:
- cron: '00 18 * * *'
name: CI
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build:
- linux-stable
- linux-musl-stable
- linux-beta
- linux-nightly
- macos-stable
- macos-stable-arm64
- windows-stable
include:
- build: linux-stable
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
rust: stable
- build: linux-musl-stable
os: ubuntu-22.04
target: x86_64-unknown-linux-musl
rust: stable
- build: linux-beta
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
rust: beta
- build: linux-nightly
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
rust: nightly
- build: macos-stable
os: macos-15-intel
target: x86_64-apple-darwin
rust: stable
- build: macos-stable-arm64
os: macos-latest
target: aarch64-apple-darwin
rust: stable
- build: windows-stable
os: windows-2022
target: x86_64-pc-windows-msvc
rust: stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- run: cargo test --target ${{ matrix.target }}
build-cross:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build: [ netbsd, freebsd ]
include:
- build: netbsd
os: ubuntu-22.04
target: x86_64-unknown-netbsd
rust: stable
- build: freebsd
os: ubuntu-22.04
target: x86_64-unknown-freebsd
rust: stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- name: Use Cross
shell: bash
run: |
cargo install cross --git https://github.com/cross-rs/cross
- name: Show command used for Cargo
run: |
echo "cargo command is: ${{ env.CARGO }}"
echo "target flag is: ${{ env.TARGET_FLAGS }}"
- name: cross build
run: cross build --target ${{ matrix.target }} --verbose
sim-test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build:
- linux-stable
- macos-stable
- windows-stable
include:
- build: linux-stable
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
rust: stable
- build: macos-stable
os: macos-15-intel
target: x86_64-apple-darwin
rust: stable
- build: windows-stable
os: windows-2022
target: x86_64-pc-windows-msvc
rust: stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
target: ${{ matrix.target }}
- uses: Swatinem/rust-cache@v2
- name: Copy wintun.dll to current dir
if: startsWith(matrix.build, 'windows')
shell: bash
# The simulation tests run from the crates/trippy-core directory and so `wintun.dll` needs to be copied there
run: |
cp "crates/trippy-core/tests/resources/wintun.dll" "./crates/trippy-core/"
- name: Allow ICMPv4 and ICMPv6 in Windows defender firewall
if: startsWith(matrix.build, 'windows')
shell: pwsh
run: |
New-NetFirewallRule -DisplayName "ICMPv4 Trippy Allow" -Name ICMPv4_TRIPPY_ALLOW -Protocol ICMPv4 -Action Allow
New-NetFirewallRule -DisplayName "ICMPv6 Trippy Allow" -Name ICMPv6_TRIPPY_ALLOW -Protocol ICMPv6 -Action Allow
- name: Build (without root)
run: cargo build --target ${{ matrix.target }} --features sim-tests --test sim
- name: Run simulation test on ${{ matrix.build }}
if: ${{ ! startsWith(matrix.build, 'windows') }}
run: sudo -E env "PATH=$PATH" cargo test --target ${{ matrix.target }} --features sim-tests --test sim -- --exact --nocapture
- name: Run simulation test on ${{ matrix.build }}
if: startsWith(matrix.build, 'windows')
run: cargo test --target ${{ matrix.target }} --features sim-tests --test sim -- --exact --nocapture
fmt:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: stable
components: rustfmt
- uses: Swatinem/rust-cache@v2
- run: cargo fmt --all -- --check
clippy:
runs-on: ${{ matrix.os }}
strategy:
matrix:
build:
- linux-stable
- macos-stable
- windows-stable
include:
- build: linux-stable
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
rust: stable
- build: macos-stable
os: macos-15-intel
target: x86_64-apple-darwin
rust: stable
- build: windows-stable
os: windows-2022
target: x86_64-pc-windows-msvc
rust: stable
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
toolchain: ${{ matrix.rust }}
components: clippy
- uses: Swatinem/rust-cache@v2
- run: cargo clippy --workspace --all-features --target ${{ matrix.target }} --tests -- -Dwarnings
build-docker:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: Build Docker image
run: docker build -t trippy-docker-image .
cargo-deny:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
with:
rust-version: "1.87.0"
log-level: warn
command: check
arguments: --all-features
command-arguments: "--hide-inclusion-graph"
cargo-msrv:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: install cargo-msrv
run: cargo install --git https://github.com/foresterre/cargo-msrv.git cargo-msrv
- name: check msrv for trippy
run: cargo msrv verify --output-format json --manifest-path crates/trippy/Cargo.toml -- cargo check
- name: check msrv for trippy-tui
run: cargo msrv verify --output-format json --manifest-path crates/trippy-tui/Cargo.toml -- cargo check
- name: check msrv for trippy-core
run: cargo msrv verify --output-format json --manifest-path crates/trippy-core/Cargo.toml -- cargo check
- name: check msrv for trippy-packet
run: cargo msrv verify --output-format json --manifest-path crates/trippy-packet/Cargo.toml -- cargo check
- name: check msrv for trippy-dns
run: cargo msrv verify --output-format json --manifest-path crates/trippy-dns/Cargo.toml -- cargo check
- name: check msrv for trippy-privilege
run: cargo msrv verify --output-format json --manifest-path crates/trippy-privilege/Cargo.toml -- cargo check
style:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: dprint/check@v2.2
conventional-commits:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Conventional Commits Lint
uses: webiny/action-conventional-commits@v1.3.0
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
allowed-commit-types: "feat,fix,chore,docs,style,refactor,test,build,ci,revert"
spelling:
runs-on: ubuntu-22.04
steps:
- name: Install cargo-spellcheck
uses: taiki-e/install-action@v2
with:
tool: cargo-spellcheck
- uses: actions/checkout@v4
- name: Run cargo-spellcheck
run: cargo spellcheck --code 1
================================================
FILE: .github/workflows/deploy.yml
================================================
on:
push:
branches: [ master ]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout your repository using git
uses: actions/checkout@v4
- name: Install, build, and upload your site
uses: withastro/action@v3
with:
path: docs
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
================================================
FILE: .github/workflows/release.yml
================================================
name: release
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
jobs:
create-release:
name: create-release
runs-on: ubuntu-latest
outputs:
upload_url: ${{ steps.release.outputs.upload_url }}
trip_version: ${{ env.TRIP_VERSION }}
steps:
- name: Get the release version from the tag
shell: bash
if: env.TRIP_VERSION == ''
run: |
echo "TRIP_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
echo "version is: ${{ env.TRIP_VERSION }}"
- name: Create GitHub release
id: release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ env.TRIP_VERSION }}
release_name: Trippy ${{ env.TRIP_VERSION }}
body: See [CHANGELOG.md](https://github.com/fujiapple852/trippy/blob/master/CHANGELOG.md) for details.
prerelease: false
build-release:
name: build-release
needs: ['create-release']
runs-on: ${{ matrix.os }}
env:
CARGO: cargo
TARGET_FLAGS: ""
TARGET_DIR: ./target
CROSS_NO_WARNINGS: 0
RUST_BACKTRACE: 1
strategy:
matrix:
build: [
x86_64-linux-gnu, x86_64-linux-musl, aarch64-linux-gnu, aarch64-linux-musl,
armv7-linux-gnueabihf, armv7-linux-musleabihf, armv7-linux-musleabi,
x86_64-apple-darwin, aarch64-apple-darwin,
x86_64-pc-windows-msvc, x86_64-pc-windows-gnu, aarch64-pc-windows-msvc,
x86_64-netbsd, x86_64-freebsd
]
include:
# Linux (x86_64 & aarch64)
- build: x86_64-linux-gnu
os: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- build: x86_64-linux-musl
os: ubuntu-22.04
target: x86_64-unknown-linux-musl
- build: aarch64-linux-gnu
os: ubuntu-22.04
target: aarch64-unknown-linux-gnu
- build: aarch64-linux-musl
os: ubuntu-22.04
target: aarch64-unknown-linux-musl
# Linux (armv7)
- build: armv7-linux-gnueabihf
os: ubuntu-22.04
target: armv7-unknown-linux-gnueabihf
- build: armv7-linux-musleabihf
os: ubuntu-22.04
target: armv7-unknown-linux-musleabihf
- build: armv7-linux-musleabi
os: ubuntu-22.04
target: armv7-unknown-linux-musleabi
# macOS (x86_64 & aarch64)
- build: x86_64-apple-darwin
os: macos-15-intel
target: x86_64-apple-darwin
- build: aarch64-apple-darwin
os: macos-latest
target: aarch64-apple-darwin
# Windows (x86_64 & aarch64)
- build: x86_64-pc-windows-msvc
os: windows-2022
target: x86_64-pc-windows-msvc
- build: x86_64-pc-windows-gnu
os: ubuntu-22.04
target: x86_64-pc-windows-gnu
- build: aarch64-pc-windows-msvc
os: windows-2022
target: aarch64-pc-windows-msvc
# BSD (x86_64)
- build: x86_64-netbsd
os: ubuntu-22.04
target: x86_64-unknown-netbsd
- build: x86_64-freebsd
os: ubuntu-22.04
target: x86_64-unknown-freebsd
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 1
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
profile: minimal
override: true
target: ${{ matrix.target }}
- name: Use Cross
shell: bash
run: |
cargo install cross --git https://github.com/cross-rs/cross
echo "CARGO=cross" >> $GITHUB_ENV
echo "TARGET_FLAGS=--target ${{ matrix.target }}" >> $GITHUB_ENV
echo "TARGET_DIR=./target/${{ matrix.target }}" >> $GITHUB_ENV
- name: Show command used for Cargo
run: |
echo "cargo command is: ${{ env.CARGO }}"
echo "target flag is: ${{ env.TARGET_FLAGS }}"
echo "target dir is: ${{ env.TARGET_DIR }}"
- name: Build release binary
run: ${{ env.CARGO }} build --verbose --release ${{ env.TARGET_FLAGS }}
- name: Build archive
shell: bash
run: |
staging="trippy-${{ needs.create-release.outputs.trip_version }}-${{ matrix.target }}"
mkdir -p "$staging"
if [ "${{ matrix.os }}" = "windows-2022" ] || [ "${{ matrix.build }}" = "x86_64-pc-windows-gnu" ]; then
cp "target/${{ matrix.target }}/release/trip.exe" "$staging/"
7z a -tzip "$staging.zip" "$staging"
echo "ASSET=$staging.zip" >> $GITHUB_ENV
else
cp "target/${{ matrix.target }}/release/trip" "$staging/"
tar czf "$staging.tar.gz" "$staging"
echo "ASSET=$staging.tar.gz" >> $GITHUB_ENV
fi
- name: Build RPM package
shell: bash
if: startsWith(matrix.build, 'x86_64-linux-gnu')
run: |
cargo install cargo-generate-rpm
cargo generate-rpm -p crates/trippy --target ${{ matrix.target }} -o target/${{ matrix.target }}/generate-rpm/trippy-${{ needs.create-release.outputs.trip_version }}-x86_64.rpm
- name: Upload RPM package
if: startsWith(matrix.build, 'x86_64-linux-gnu')
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: target/${{ matrix.target }}/generate-rpm/trippy-${{ needs.create-release.outputs.trip_version }}-x86_64.rpm
asset_name: trippy-${{ needs.create-release.outputs.trip_version }}-x86_64.rpm
asset_content_type: application/x-rpm
- name: Create Debian package
shell: bash
if: startsWith(matrix.build, 'x86_64-linux-gnu') || startsWith(matrix.build, 'x86_64-linux-musl')
run: |
cargo install cargo-deb
cargo deb -p trippy --target ${{ matrix.target }} --deb-version ${{ needs.create-release.outputs.trip_version }}
case ${{ matrix.target }} in
aarch64-*-linux-*) DPKG_ARCH=arm64 ;;
arm-*-linux-*hf) DPKG_ARCH=armhf ;;
i686-*-linux-*) DPKG_ARCH=i686 ;;
x86_64-*-linux-*) DPKG_ARCH=amd64 ;;
*) DPKG_ARCH=notset ;;
esac;
echo "DPKG_ARCH=${DPKG_ARCH}" >> $GITHUB_ENV
- name: Upload Deb Release Asset
if: startsWith(matrix.build, 'x86_64-linux-gnu') || startsWith(matrix.build, 'x86_64-linux-musl')
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_content_type: application/vnd.debian.binary-package
asset_path: target/${{ matrix.target }}/debian/trippy_${{ needs.create-release.outputs.trip_version }}_${{ env.DPKG_ARCH }}.deb
asset_name: trippy_${{ matrix.target }}_${{ needs.create-release.outputs.trip_version }}_${{ env.DPKG_ARCH }}.deb
- name: Upload release archive
uses: actions/upload-release-asset@v1.0.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.create-release.outputs.upload_url }}
asset_path: ${{ env.ASSET }}
asset_name: ${{ env.ASSET }}
asset_content_type: application/octet-stream
================================================
FILE: .gitignore
================================================
/target
.idea
.DS_Store
.vscode/launch.json
*.snap.new
================================================
FILE: AGENTS.md
================================================
# Trippy Agent Guidelines
This repository follows the guidance below when making changes.
## Development commands
- Check the code with `cargo check --workspace --all-features --tests`.
- Test the code with `cargo test`. Do not pass `--all-features`.
- Format Rust code with `cargo fmt --all`.
- Format non-Rust code with `dprint fmt` (install with `cargo install --locked dprint`).
- Lint with `cargo clippy --workspace --all-features --tests -- -Dwarnings`.
- If CLI arguments, man pages or shell completions change, update snapshots:
`cargo test && cargo insta review`.
- If the `Dockerfile` changes, build it locally using `docker build . -t trippy:dev`.
## Commit messages
- Use the Conventional Commits format:
`<type>[optional scope]: <description>` where `<type>` is one of
`feat`, `fix`, `chore`, `docs`, `style`, `refactor`, `test`, `build`, `ci`, or `revert`.
- For code changes set the scope to one of `core`, `dns`, `packet`, `privilege` or `tui`.
- Use backquotes for file names and code items in the description.
- For documentation fixes use `docs: fix <description>`.
- Prefer small, focused commits. For larger changes, use multiple commits with clear messages.
## Recommendations
- Run test, format and clippy before submitting a pull request and ensure all CI checks pass.
- Keep documentation and examples in sync with code changes.
- Use feature branches for separate tasks.
- Open issues and pull requests through GitHub for discussion and review.
- Always rebase your branch before when editing an open pull request to keep the history clean.
================================================
FILE: CHANGELOG.md
================================================
# 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.0.0/), and this project adheres
to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Added translations for locale `zh-TW` ([#1630](https://github.com/fujiapple852/trippy/pull/1630))
### Changed
- [BREAKING CHANGE] Change default `address-family` to be
`system` ([#1475](https://github.com/fujiapple852/trippy/issues/1475))
- Increase MSRV to 1.85 ([#1700](https://github.com/fujiapple852/trippy/issues/1700))
### Fixed
- Default the `system` `address-family` to `ipv4-then-ipv6` for non-`system`
resolvers ([#1635](https://github.com/fujiapple852/trippy/issues/1635))
- Locale parsing fails for valid BCP 47 language tags ([#1631](https://github.com/fujiapple852/trippy/pull/1631))
## [0.13.0] - 2025-05-05
### Added
- Added DSCP and ECN columns ([#1539](https://github.com/fujiapple852/trippy/issues/1539))
- Added support for setting IPv6 traffic class from `--tos` ([#202](https://github.com/fujiapple852/trippy/issues/202))
- Added ability to read config from `$XDG_CONFIG_HOME/trippy`
directory ([#1528](https://github.com/fujiapple852/trippy/issues/1528))
- Added `--tui-timezone` flag to set a custom timezone ([#1513](https://github.com/fujiapple852/trippy/issues/1513))
- Added support for `--addr-family system` to defer address family selection to the OS
resolver ([#1469](https://github.com/fujiapple852/trippy/issues/1469))
- Added tracing start and end timestamps to the `json`
report ([#1510](https://github.com/fujiapple852/trippy/issues/1510))
- Added the Trippy logo! ([#100](https://github.com/fujiapple852/trippy/issues/100))
### Changed
- Remove address family downgrade for `dublin` strategy ([#1476](https://github.com/fujiapple852/trippy/issues/1476))
- Reduce verbosity of tracing for library users ([#1482](https://github.com/fujiapple852/trippy/issues/1482))
- Increase MSRV to 1.78 ([#1576](https://github.com/fujiapple852/trippy/issues/1576))
### Fixed
- Tracer panic for large icmp packets ([#1561](https://github.com/fujiapple852/trippy/issues/1561))
- Memory corruption on Windows ([#1527](https://github.com/fujiapple852/trippy/issues/1527))
- Socket being closed twice on Windows ([#1443](https://github.com/fujiapple852/trippy/issues/1443))
- Potential crash on Windows for adapters without unicast
addresses ([#1547](https://github.com/fujiapple852/trippy/issues/1547))
- Potential use-after-free when discovering source address on
Windows ([#1558](https://github.com/fujiapple852/trippy/issues/1558))
- The `--tos` (`-Q`) flag is ignored for `IPv4/udp`
tracing ([#1540](https://github.com/fujiapple852/trippy/issues/1540))
- Items missing from settings dialog ([#1541](https://github.com/fujiapple852/trippy/issues/1541))
## [0.12.2] - 2025-01-03
### Fixed
- Tracer panic when `--first-ttl` is greater than 1 ([#1460](https://github.com/fujiapple852/trippy/issues/1460))
- IP `--addr-family` not respected for
`--dns-resolve-method resolv` ([#1461](https://github.com/fujiapple852/trippy/issues/1461))
- Incorrect cli help text for `--addr-family` ([#1456](https://github.com/fujiapple852/trippy/issues/1456))
## [0.12.1] - 2024-12-21
### Changed
- Replace use of `yaml` with `toml` dependency ([#1416](https://github.com/fujiapple852/trippy/issues/1416))
### Fixed
- Locale data not copied into docker image ([#1431](https://github.com/fujiapple852/trippy/issues/1431))
## [0.12.0] - 2024-12-04
### Added
- Highlight lost probes in sample history ([#1247](https://github.com/fujiapple852/trippy/issues/1247))
- Added `quit-preserve-screen` (default: `shift+q`) key binding to quit Tui without clearing the
screen ([#1382](https://github.com/fujiapple852/trippy/issues/1382))
- Added forward add backward loss heuristics ([#860](https://github.com/fujiapple852/trippy/issues/860))
- Added `--tui-locale` flag to support i18n ([#1319](https://github.com/fujiapple852/trippy/issues/1319))
- Added translations for locales `en`, `fr`, `tr`, `zh`, `pt`, `sv`, `it`, `ru`, `es` &
`de` ([#506](https://github.com/fujiapple852/trippy/issues/506))
- Added `--print-locales` flag to print all available
locales ([#1357](https://github.com/fujiapple852/trippy/issues/1357))
- Added Debian package ([#1312](https://github.com/fujiapple852/trippy/issues/1312))
- Added Ubuntu `noble` PPA package ([#1308](https://github.com/fujiapple852/trippy/issues/1308))
### Changed
- Added information bar to Tui ([#1349](https://github.com/fujiapple852/trippy/issues/1349))
- [BREAKING CHANGE] Remove `Timestamp` from all `DnsEntry`
variants ([#1296](https://github.com/fujiapple852/trippy/issues/1296))
- [BREAKING CHANGE] Replace `toggle-privacy` key binding with `expand-privacy` and
`contract-privacy` ([#1347](https://github.com/fujiapple852/trippy/issues/1347))
- [BREAKING CHANGE] Hide source address when `--tui-privacy-max-ttl` is
set ([#1365](https://github.com/fujiapple852/trippy/issues/1365))
- Only show hostnames if different from IPs ([#1363](https://github.com/fujiapple852/trippy/issues/1363))
- Lookup GeoIp with current locale ([#1336](https://github.com/fujiapple852/trippy/issues/1336))
- Enable Link-Time Optimization (LTO) for release builds ([#1341](https://github.com/fujiapple852/trippy/issues/1341))
### Fixed
- Reverse dns enqueued multiple times when dns-ttl expires ([#1290](https://github.com/fujiapple852/trippy/issues/1290))
- Fixed panic for icmp extensions with malformed length ([#1287](https://github.com/fujiapple852/trippy/issues/1287))
- Cursor not moved to the bottom on exit when using
`--tui-preserve-screen` ([#1375](https://github.com/fujiapple852/trippy/issues/1375))
- Config item `tui-address-mode` does not accept `ip` ([#1327](https://github.com/fujiapple852/trippy/issues/1327))
- Icmp extension mode not shown in Tui settings ([#1289](https://github.com/fujiapple852/trippy/issues/1289))
- Sample history and frequency charts ignore sub-millisecond
samples ([#1398](https://github.com/fujiapple852/trippy/issues/1398))
## [0.11.0] - 2024-08-11
### Added
- Added NAT detection for `IPv4/udp/dublin` ([#1104](https://github.com/fujiapple852/trippy/issues/1104))
- Added public API ([#1192](https://github.com/fujiapple852/trippy/issues/1192))
- Added support for NAT detection (`N`) column ([#1219](https://github.com/fujiapple852/trippy/issues/1219))
- Added support for last icmp packet type (`T`) column ([#1105](https://github.com/fujiapple852/trippy/issues/1105))
- Added support for last icmp packet code (`C`) column ([#1109](https://github.com/fujiapple852/trippy/issues/1109))
- Added support for the probe failure count (`f`) column ([#1258](https://github.com/fujiapple852/trippy/issues/1258))
- Added settings dialog tab hotkeys ([#1217](https://github.com/fujiapple852/trippy/issues/1217))
- Added `--dns-ttl` flag to allow refreshing the reverse DNS
results ([#1233](https://github.com/fujiapple852/trippy/issues/1233))
- Added `--generate-man` flag for generating [ROFF](https://en.wikipedia.org/wiki/Roff_(software)) man
page ([#85](https://github.com/fujiapple852/trippy/issues/85))
- Added Ubuntu PPA package ([#859](https://github.com/fujiapple852/trippy/issues/859))
- Added Chocolatey package ([#572](https://github.com/fujiapple852/trippy/issues/572))
### Changed
- [BREAKING CHANGE] Changed initial sequence to be `33434` ([#1203](https://github.com/fujiapple852/trippy/issues/1203))
- [BREAKING CHANGE] Renamed `tui-max-[samples|flows]`
as `max-[samples|flows]` ([#1187](https://github.com/fujiapple852/trippy/issues/1187))
- Separated library and binary crates ([#1141](https://github.com/fujiapple852/trippy/issues/1141))
- Record `icmp` packet code ([#734](https://github.com/fujiapple852/trippy/issues/734))
- Transient error handling for `IPv4` on macOS, Linux &
Windows ([#1255](https://github.com/fujiapple852/trippy/issues/1255))
- Improved error messages ([#1150](https://github.com/fujiapple852/trippy/issues/1150))
- Revamp the help dialog ([#1260](https://github.com/fujiapple852/trippy/issues/1260))
### Fixed
- Fixed `DestinationUnreachable` incorrectly assumed to come from target
host ([#1225](https://github.com/fujiapple852/trippy/issues/1225))
- Fixed incorrect target hop calculation ([#1226](https://github.com/fujiapple852/trippy/issues/1226))
- Do not conflate `AddressInUse` and `AddrNotAvailable`
errors ([#1246](https://github.com/fujiapple852/trippy/issues/1246))
## [0.10.0] - 2024-03-31
### Added
- Added support for calculating and displaying jitter ([#39](https://github.com/fujiapple852/trippy/issues/39))
- Added support for customizing columns ([#757](https://github.com/fujiapple852/trippy/issues/757))
- Added support for reordering and toggling column
visibility in Tui ([#1026](https://github.com/fujiapple852/trippy/issues/1026))
- Added support for [dublin](https://github.com/insomniacslk/dublin-traceroute) ECMP routing
for `IPv6/udp` ([#272](https://github.com/fujiapple852/trippy/issues/272))
- Added support for [IPinfo](https://ipinfo.io) flavoured `mmdb`
files ([#862](https://github.com/fujiapple852/trippy/issues/862))
- Added support for `IPv4->IPv6` and `IPv6->IPv4` DNS fallback
modes ([#864](https://github.com/fujiapple852/trippy/issues/864))
- Added [TUN](https://en.wikipedia.org/wiki/TUN/TAP) based simulation
tests ([#908](https://github.com/fujiapple852/trippy/issues/908))
- Added support for last src port (`S`) and last dest port (`P`) custom
columns ([#974](https://github.com/fujiapple852/trippy/issues/974))
- Added support for last sequence (`Q`) custom column ([#976](https://github.com/fujiapple852/trippy/issues/976))
- Added support for more named theme colors ([#1011](https://github.com/fujiapple852/trippy/issues/1011))
### Changed
- Ensure `paris` and `dublin` ECMP strategy are only used with supported
protocols ([#848](https://github.com/fujiapple852/trippy/issues/848))
- Restrict flows to `paris` and `dublin` ECMP strategies ([#1007](https://github.com/fujiapple852/trippy/issues/1007))
- Improved Tui table column layout logic ([#925](https://github.com/fujiapple852/trippy/issues/925))
- Use exclusive reference `&mut` for all Socket operations ([#843](https://github.com/fujiapple852/trippy/issues/843))
- Reduced maximum sequence per round from 1024 to 512 ([#1067](https://github.com/fujiapple852/trippy/issues/1067))
### Fixed
- Fixed off-by-one bug in max-rounds calculation ([#906](https://github.com/fujiapple852/trippy/issues/906))
- Fixed panic with `expand-hosts-max` Tui command ([#892](https://github.com/fujiapple852/trippy/issues/892))
- Fixed failure to parse generated config file on Windows ([#958](https://github.com/fujiapple852/trippy/issues/958))
- Fixed tracer panic for `icmp` TimeExceeded "Fragment reassembly time exceeded"
packets ([#979](https://github.com/fujiapple852/trippy/issues/979))
- Fixed tracer not discarding unrelated `icmp` packets for `udp` and `tcp`
protocols ([#982](https://github.com/fujiapple852/trippy/issues/982))
- Fixed incorrect minimum packet size for `IPv6` ([#985](https://github.com/fujiapple852/trippy/issues/985))
- Fixed permission denied error reading configuration file from snap
installation ([#1058](https://github.com/fujiapple852/trippy/issues/1058))
## [0.9.0] - 2023-11-30
### Added
- Added support for tracing flows ([#776](https://github.com/fujiapple852/trippy/issues/776))
- Added support for `icmp` extensions ([#33](https://github.com/fujiapple852/trippy/issues/33))
- Added support for `MPLS` label stack class `icmp` extension
objects ([#753](https://github.com/fujiapple852/trippy/issues/753))
- Added support for [paris](https://github.com/libparistraceroute/libparistraceroute) ECMP routing
for `IPv6/udp` ([#749](https://github.com/fujiapple852/trippy/issues/749))
- Added `--unprivileged` (`-u`) flag to allow tracing without elevated privileges (macOS
only) ([#101](https://github.com/fujiapple852/trippy/issues/101))
- Added `--tui-privacy-max-ttl` flag to hide host and IP details for low ttl
hops ([#766](https://github.com/fujiapple852/trippy/issues/766))
- Added `toggle-privacy` (default: `p`) key binding to show or hide private
hops ([#823](https://github.com/fujiapple852/trippy/issues/823))
- Added `toggle-flows` (default: `f`) key binding to show or hide tracing
flows ([#777](https://github.com/fujiapple852/trippy/issues/777))
- Added `--dns-resolve-all` (`-y`) flag to allow tracing to all IPs resolved from DNS lookup
entry ([#743](https://github.com/fujiapple852/trippy/issues/743))
- Added `dot` report mode (`-m dot`) to output hop graph in Graphviz `DOT`
format ([#582](https://github.com/fujiapple852/trippy/issues/582))
- Added `flows` report mode (`-m flows`) to output a list of all unique tracing
flows ([#770](https://github.com/fujiapple852/trippy/issues/770))
- Added `--icmp-extensions` (`-e`) flag for parsing `IPv4`/`IPv6` `icmp`
extensions ([#751](https://github.com/fujiapple852/trippy/issues/751))
- Added `--tui-icmp-extension-mode` flag to control how `icmp` extensions are
rendered ([#752](https://github.com/fujiapple852/trippy/issues/752))
- Added `--print-config-template` flag to output a template config
file ([#792](https://github.com/fujiapple852/trippy/issues/792))
- Added `--icmp` flag as a shortcut for `--protocol icmp` ([#649](https://github.com/fujiapple852/trippy/issues/649))
- Added `toggle-help-alt` (default: `?`) key binding to show or hide
help ([#694](https://github.com/fujiapple852/trippy/issues/694))
- Added panic handing to Tui ([#784](https://github.com/fujiapple852/trippy/issues/784))
- Added official Windows `scoop` package ([#462](https://github.com/fujiapple852/trippy/issues/462))
- Added official Windows `winget` package ([#460](https://github.com/fujiapple852/trippy/issues/460))
- Release `musl` Debian `deb` binary asset ([#568](https://github.com/fujiapple852/trippy/issues/568))
- Release `armv7` Linux binary assets ([#712](https://github.com/fujiapple852/trippy/issues/712))
- Release `aarch64-apple-darwin` (aka macOS Apple Silicon) binary
assets ([#801](https://github.com/fujiapple852/trippy/issues/801))
- Added additional Rust Tier 1 and Tier 2 binary assets ([#811](https://github.com/fujiapple852/trippy/issues/811))
### Changed
- [BREAKING CHANGE] `icmp` extension object data added to `json` and `stream`
reports ([#806](https://github.com/fujiapple852/trippy/issues/806))
- [BREAKING CHANGE] IPs field added to `csv` and all tabular
reports ([#597](https://github.com/fujiapple852/trippy/issues/597))
- [BREAKING CHANGE] Command line flags `--dns-lookup-as-info` and `--tui-preserve-screen` no longer require a boolean
argument ([#708](https://github.com/fujiapple852/trippy/issues/708))
- [BREAKING CHANGE] Default key binding for `ToggleFreeze` changed from `f`
to `ctrl+f` ([#785](https://github.com/fujiapple852/trippy/issues/785))
- Always render AS lines in hop details mode ([#825](https://github.com/fujiapple852/trippy/issues/825))
- Expose DNS resolver module as part of `trippy` library ([#754](https://github.com/fujiapple852/trippy/issues/754))
- Replaced unmaintained `tui-rs` crate with `ratatui` crate ([#569](https://github.com/fujiapple852/trippy/issues/569))
### Fixed
- Reverse DNS lookup not working in reports ([#509](https://github.com/fujiapple852/trippy/issues/509))
- Crash on NetBSD during window resizing ([#276](https://github.com/fujiapple852/trippy/issues/276))
- Protocol mismatch causes tracer panic ([#745](https://github.com/fujiapple852/trippy/issues/745))
- Incorrect row height in Tui hop detail navigation view for hops with no
responses ([#765](https://github.com/fujiapple852/trippy/issues/765))
- Unnecessary socket creation in certain tracing modes ([#647](https://github.com/fujiapple852/trippy/issues/647))
- Incorrect byte order in `IPv4` packet length calculation ([#686](https://github.com/fujiapple852/trippy/issues/686))
## [0.8.0] - 2023-05-15
### Added
- Added `--tui-as-mode` flag to control how AS information is
rendered ([#483](https://github.com/fujiapple852/trippy/issues/483))
- Added support for configuration files and added a `-c` (`--config-file`)
flag ([#412](https://github.com/fujiapple852/trippy/issues/412))
- Added `--generate` flag for generating shell completions ([#86](https://github.com/fujiapple852/trippy/issues/86))
- Added support for showing and navigating host detail ([#70](https://github.com/fujiapple852/trippy/issues/70))
- Added `--geoip-mmdb-file` and `--tui-geoip-mode` flags for looking up and displaying GeoIp information from `mmdb`
files ([#503](https://github.com/fujiapple852/trippy/issues/503))
- Added settings dialog and simplified Tui header display ([#521](https://github.com/fujiapple852/trippy/issues/521))
- Added interactive GeoIp map display ([#505](https://github.com/fujiapple852/trippy/issues/505))
- Added support for the [paris](https://github.com/libparistraceroute/libparistraceroute) ECMP traceroute strategy
for `IPv4/udp` ([#542](https://github.com/fujiapple852/trippy/issues/542))
- Added `silent` reporting mode to run tracing without producing any
output ([#555](https://github.com/fujiapple852/trippy/issues/555))
- Added `-v` (`--verbose`), `--log-format`, `--log-filter` & `--log-span-events` flags to support generating debug trace
logging output ([#552](https://github.com/fujiapple852/trippy/issues/552))
### Changed
- Show AS information for IP addresses without PTR record ([#479](https://github.com/fujiapple852/trippy/issues/479))
- Re-enabled musl release builds ([#456](https://github.com/fujiapple852/trippy/issues/456))
- [BREAKING CHANGE] Renamed short config flag for `report-cycles` from `-c`
to `-C` ([#491](https://github.com/fujiapple852/trippy/issues/491))
- Ensure administrator privileges on Windows ([#451](https://github.com/fujiapple852/trippy/issues/451))
- Add context information to socket errors ([#153](https://github.com/fujiapple852/trippy/issues/153))
### Fixed
- Do not require passing targets for certain command line
flags ([#500](https://github.com/fujiapple852/trippy/issues/500))
- Key press registering two events on Windows ([#513](https://github.com/fujiapple852/trippy/issues/513))
- Command line parameter names in error messages should be
in `kebab-case` ([#516](https://github.com/fujiapple852/trippy/issues/516))
## [0.7.0] - 2023-03-25
### Added
- Added support for Windows (`icmp`, `udp` & `tcp`
for `IPv4` &`IPv6`) ([#98](https://github.com/fujiapple852/trippy/issues/98))
- Added support for custom Tui key bindings ([#448](https://github.com/fujiapple852/trippy/issues/448))
- Added support for custom Tui color themes ([#411](https://github.com/fujiapple852/trippy/issues/411))
- Added RPM packaging ([#95](https://github.com/fujiapple852/trippy/issues/95))
- Added DEB packaging ([#94](https://github.com/fujiapple852/trippy/issues/94))
### Fixed
- Variable Equal Cost Multi-path Routing (ECMP) causing truncated
trace ([#269](https://github.com/fujiapple852/trippy/issues/269))
- Tracing using the `tcp` may ignore some incoming `icmp`
responses ([#407](https://github.com/fujiapple852/trippy/issues/407))
- Tracer panics with large `--initial-sequence` and delayed TCP probe
response ([#435](https://github.com/fujiapple852/trippy/issues/435))
- Trippy Docker fails to start ([#277](https://github.com/fujiapple852/trippy/issues/277))
## [0.6.0] - 2022-08-19
### Added
- Added support for tracing using `IPv6` for `tcp` ([#191](https://github.com/fujiapple852/trippy/issues/191))
- Added `-R` (`--multipath-strategy`) flag to allow setting
the [Equal Cost Multi-path Routing](https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing) strategy and added
support for the [dublin](https://github.com/insomniacslk/dublin-traceroute)
traceroute strategies for `IPv4/udp` ([#158](https://github.com/fujiapple852/trippy/issues/158))
- Added zoom-able chart showing round trip times for all hops in a
trace ([#209](https://github.com/fujiapple852/trippy/issues/209))
- Added `--udp` and `--tcp` flags as shortcuts to `-p udp` and `-p tcp`
respectively ([#205](https://github.com/fujiapple852/trippy/issues/205))
### Changed
- Gray out hops which did not update in the current round ([#216](https://github.com/fujiapple852/trippy/issues/216))
## [0.5.0] - 2022-06-02
### Added
- Added support for tracing using `IPv6` for `icmp` and `udp` ([#35](https://github.com/fujiapple852/trippy/issues/35))
- Added BSOD error reporting to Tui ([#179](https://github.com/fujiapple852/trippy/issues/179))
- Added Ctrl-C keyboard command to quit the Tui ([#91](https://github.com/fujiapple852/trippy/issues/91))
### Changed
- Rewrite of network code to use RAW sockets ([#195](https://github.com/fujiapple852/trippy/issues/195),
[#192](https://github.com/fujiapple852/trippy/issues/192))
### Fixed
- Setting `-c` (`--report-cycles`) to 1 returns no traces ([#189](https://github.com/fujiapple852/trippy/issues/189))
- Tracer failures not being shown for reports ([#183](https://github.com/fujiapple852/trippy/issues/183))
## [0.4.0] - 2022-05-18
### Added
- Added `-P` (`--target-port`) flag to allow specifying the target
port ([1](https://github.com/fujiapple852/trippy/commit/5773fe5e5323543612be6bd4606db5aa8347d71e),
[2](https://github.com/fujiapple852/trippy/commit/9f03047dd231b10b13911fcc7af60afbb8b21473))
- Added ability to trace with either a fixed source or a fixed destination port for both `udp` and `tcp`
tracing ([#43](https://github.com/fujiapple852/trippy/issues/43))
- Display source and destination ports in Tui ([#156](https://github.com/fujiapple852/trippy/issues/156))
- Added the `-A` (`--source-address`) flag to allow specifying the source
address ([#162](https://github.com/fujiapple852/trippy/issues/162))
- Added the `-I` (`--interface`) flag to allow specifying the source
interface ([#142](https://github.com/fujiapple852/trippy/issues/42))
- Added the `-Q` (`--tos`) flag to allow specifying the `TOS` (`DSCP`+`ECN`) `IPv4` header
value ([#38](https://github.com/fujiapple852/trippy/issues/38))
### Changed
- Changed `tcp` tracing to use a standard (non-raw) socket to be able to detect the
target ([#134](https://github.com/fujiapple852/trippy/issues/134))
- Changed `udp` tracing to use a standard (non-raw) socket ([#155](https://github.com/fujiapple852/trippy/issues/155))
- Renamed the `--tui-max-addresses-per-hop` flag
as `tui-max-addrs` ([#165](https://github.com/fujiapple852/trippy/issues/165))
- Reorder the cli flags in the help output ([#163](https://github.com/fujiapple852/trippy/issues/163))
- Change short alias for flag `max_round_duration` from `-I`
to `-T` ([1](https://github.com/fujiapple852/trippy/commit/15978b0909139bb2b38baa4c6f6ca969c818fc75))
- Added short cli flags for `source-port` (`-S`), `first-ttl` (`-f`) and `tui-max-addrs` (
`-M`) ([1](https://github.com/fujiapple852/trippy/commit/6a6a490174582c8500972b89407ba8d694c4c6fa))
### Fixed
- Checksums for `udp` packets were not being set (obsoleted
by [#155](https://github.com/fujiapple852/trippy/issues/155)) ([#159](https://github.com/fujiapple852/trippy/issues/159))
- `TimeExceeded` responses _from_ the target address were not being
handled ([1](https://github.com/fujiapple852/trippy/commit/3afa41326a33287a3ad9c17713dd7426ca86b481))
- The largest time-to-live for a given round was being calculated incorrectly in some
cases ([1](https://github.com/fujiapple852/trippy/commit/688a8d00d84a816449cfee48b2d6f6dd90946511))
## [0.3.1] - 2022-05-09
### Fixed
- Local IPv4 discovery fails on some platforms ([#133](https://github.com/fujiapple852/trippy/issues/133),
[#142](https://github.com/fujiapple852/trippy/issues/142))
- DNS resolution not filtering for `IPv4` addresses ([#148](https://github.com/fujiapple852/trippy/issues/148))
- Note: see [#35](https://github.com/fujiapple852/trippy/issues/35) for the status of `IPv6` support
## [0.3.0] - 2022-05-08
### Added
- Added ability for `icmp` tracing to multiple targets simultaneously in
Tui ([#72](https://github.com/fujiapple852/trippy/issues/72))
- Added ability to enable and disable the `AS` lookup from the
Tui ([#126](https://github.com/fujiapple852/trippy/issues/126))
- Added ability to switch between hop address display modes (ip, hostname or both) in thr
Tui ([#124](https://github.com/fujiapple852/trippy/issues/124))
- Added ability to expand and collapse the number of hosts displays per hop in the
Tui ([#124](https://github.com/fujiapple852/trippy/issues/124))
- Added the `-s` (`--tui-max-samples`) flag to specify the number of samples to keep for analysis and
display ([#110](https://github.com/fujiapple852/trippy/issues/110))
- Added ability to flush the DNS cache from the Tui ([#71](https://github.com/fujiapple852/trippy/issues/371))
### Changed
- Simplified `Tracer` by removing circular buffer ([#106](https://github.com/fujiapple852/trippy/issues/106))
- Added round end reason indicator to `Tracer` ([#88](https://github.com/fujiapple852/trippy/issues/88))
- Show better error message for failed DNS resolution ([#119](https://github.com/fujiapple852/trippy/issues/119))
### Fixed
- Tracing with `udp` protocol not showing the target hop due to incorrect handling of `DestinationUnreachable`
responses ([#131](https://github.com/fujiapple852/trippy/issues/131))
- Tui failing on shutdown on Windows due to `DisableMouseCapture` being invoked without a prior `EnableMouseCapture`
call ([#116](https://github.com/fujiapple852/trippy/issues/116))
- Build failing on Windows due to incorrect conditional compilation
configuration ([#113](https://github.com/fujiapple852/trippy/issues/113))
- Tracing not publishing all `Probe` in a round when the round ends without finding the
target ([#103](https://github.com/fujiapple852/trippy/issues/103))
- Tracing with `tcp` protocol not working as the checksum was not
set ([#79](https://github.com/fujiapple852/trippy/issues/79))
- Do not show FQDN for reverse DNS queries from non-system
resolvers ([#120](https://github.com/fujiapple852/trippy/issues/120))
## [0.2.0] - 2022-04-29
### Added
- Added the `-r` (`--dns-resolve-method`) flag to specify using either the OS DNS resolver (default), a 3rd party
resolver (Google `8.8.8.8` and Cloudflare `1.1.1.1`) or DNS resolver configuration from the `/etc/resolv.conf` file
- Added the `-z` (`--dns-lookup-as-info`) flag to display the ASN for each discovered host. This is not yet supported
for the default `system` resolver, see [#66](https://github.com/fujiapple852/trippy/issues/66).
- Added the `--dns-timeout` flag to allow setting a timeout on all DNS queries
- Added additional parameter validation for `first-ttl`, `max-ttl` & `initial-sequence`
### Changed
- All DNS queries are now non-blocking to prevent the Tui from freezing during slow DNS query
- Renamed `min-sequence` flag as `initial-sequence`
### Fixed
- Fixed the behaviour when the sequence number wraps around at `2^16 - 1`
## [0.1.0] - 2022-04-27
### Added
- Initial WIP release of `trippy`
[Unreleased]: https://github.com/fujiapple852/trippy/compare/0.13.0...master
[0.13.0]: https://github.com/fujiapple852/trippy/compare/0.12.2...0.13.0
[0.12.2]: https://github.com/fujiapple852/trippy/compare/0.12.1...0.12.2
[0.12.1]: https://github.com/fujiapple852/trippy/compare/0.12.0...0.12.1
[0.12.0]: https://github.com/fujiapple852/trippy/compare/0.11.0...0.12.0
[0.11.0]: https://github.com/fujiapple852/trippy/compare/0.10.0...0.11.0
[0.10.0]: https://github.com/fujiapple852/trippy/compare/0.9.0...0.10.0
[0.9.0]: https://github.com/fujiapple852/trippy/compare/0.8.0...0.9.0
[0.8.0]: https://github.com/fujiapple852/trippy/compare/0.7.0...0.8.0
[0.7.0]: https://github.com/fujiapple852/trippy/compare/0.6.0...0.7.0
[0.6.0]: https://github.com/fujiapple852/trippy/compare/0.5.0...0.6.0
[0.5.0]: https://github.com/fujiapple852/trippy/compare/0.4.0...0.5.0
[0.4.0]: https://github.com/fujiapple852/trippy/compare/0.3.1...0.4.0
[0.3.1]: https://github.com/fujiapple852/trippy/compare/0.3.0...0.3.1
[0.3.0]: https://github.com/fujiapple852/trippy/compare/0.2.0...0.3.0
[0.2.0]: https://github.com/fujiapple852/trippy/compare/0.1.0...0.2.0
[0.1.0]: https://github.com/fujiapple852/trippy/compare/0.0.0...0.1.0
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to Trippy
Contributions to Trippy are most welcome, whether you wish to report a bug, request a feature, or contribute code.
Raise issues and feature requests in the GitHub [issue tracker](https://github.com/fujiapple852/trippy/issues) and raise
all changes as GitHub [pull requests](https://github.com/fujiapple852/trippy/pulls).
## Development
This section describes how to set up a development environment and the development process for Trippy.
### Development tools
The following tools are needed for local development. Note that most of the following are checked during CI, so it is
recommended to run these checks locally before submitting a pull request.
#### Rust
Trippy is written in [`Rust`](https://www.rust-lang.org/tools/install) and requires the Rust toolchain to build and run.
As well as default components such as `cargo`, you will need `rustfmt` and `clippy` for code formatting and linting.
> [!NOTE]
> Trippy uses the `stable` toolchain.
To install `rustfmt` and `clippy`:
```shell
rustup component add rustfmt clippy
```
To format the Rust code:
```shell
cargo fmt --all
```
> [!NOTE]
> Trippy uses default settings for code formatting.
To lint the Rust code:
```shell
cargo clippy --workspace --all-features --tests -- -Dwarnings
```
> [!NOTE]
> Clippy configuration is defined at the workspace level in the root `Cargo.toml` file.
#### Cargo `deny`
If you add or update dependencies, you must run Cargo [`deny`](https://github.com/EmbarkStudios/cargo-deny) to ensure
that the licenses of the dependencies are acceptable.
```shell
cargo deny check --hide-inclusion-graph
```
The allowed licenses are defined in the `deny.toml` file.
#### Cargo `insta`
If you make changes that impact the command line interface arguments, manual pages or shell completions, you must update
the testing snapshots using Cargo [`insta`](https://insta.rs).
After making your changes, run `cargo test` to generate the new snapshots followed by `cargo insta` to review and update
the snapshots.
```shell
cargo test && cargo insta review
```
#### Cargo `spelling`
If you make changes to code documentation, you must run Cargo [`spellcheck`](https://github.com/drahnr/cargo-spellcheck)
to ensure they are free from misspellings and typos.
To check the spelling:
```shell
cargo spellcheck check
```
The configuration for `spellcheck` is defined in the `.config/spellcheck.toml` file and the custom dictionary is defined
in the `.config/trippy.dic` file.
#### Cargo `msrv`
If you add or update dependencies, you should use the Cargo [msrv](https://github.com/foresterre/cargo-msrv) tool to
check the Minimum Supported Rust Version (MSRV) to ensure that the new dependencies are compatible with the current
MSRV.
To check the MSRV of the `trippy` crate:
```shell
cargo msrv verify --manifest-path crates/trippy/Cargo.toml-- cargo check
```
#### `dprint`
The [`dprint`](https://dprint.dev/) tool is needed to ensure consistent formatting of the non-Rust portions of the
codebase and docs.
To format the non-Rust code:
```shell
dprint fmt
```
The configuration for `dprint` is defined in the `dprint.json` file.
#### Docker
If you make changes to the `Dockerfile`, you should build the Docker image locally to ensure it builds correctly.
```shell
docker build . -t trippy:dev
```
> [!NOTE]
> If you add new files that are required at build time then you must update the `Dockerfile` to include them explicitly.
### Development process
This section describes the development process for Trippy.
#### Conventional commits
All commit messages should follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format.
The commit message should be structured as follows:
```text
<type>[optional scope]: <description>
```
Where `type` is one of the following:
- `feat`: A new feature
- `fix`: A bug fix
- `chore`: Build process, dependency and version updates
- `docs`: Documentation only changes
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
- `refactor`: A code change that neither fixes a bug nor adds a feature
- `test`: Adding missing tests or correcting existing tests
- `build`: Changes that affect the build system or external dependencies
- `ci`: Changes to our CI configuration files and scripts
- `revert`: Reverts a previous commit
The `scope` is optional and, if given, should be the name of the crate being modified, currently one of `core`,
`packet`, `dns`, `privilege`, `tui` or `trippy`.
> [!NOTE]
> Small do-one-things commits are preferred over large do-many-things commits. This makes changes easier to review and
> revert if necessary. For example, if you are adding a new feature and fixing a bug, it is better to create two
> separate commits.
## Releases
Instructions for releasing a new `0.xx.0` version of Trippy.
Many distribution packages are managed by external maintainers, however the following are managed by the Trippy
maintainers:
- GitHub Releases
- Crates.io
- Docker
- Snapcraft
- WinGet
- Ubuntu PPA
### Prerequisites
- Check the MSRV (Minimum Supported Rust Version) in the `trippy` crate `Cargo.toml` is still correct.
> [!NOTE]
> The MSRV should typically be the version from around 1 year before the current date to maximise compatibility.
- Update all dependencies to the latest SemVer compatible versions
> [!NOTE]
> Some distributions may not support the latest versions of all dependencies, so be conservative with updates.
- Record and add an `assets/0.xx.0/demo.gif` for the new version
- Update the `README.md` with details of the features in the new version
- Update the `CHANGELOG.md` for the new version
- Update the `RELEASES.md` for the new version
- Update the version to `0.xx.0` in `Cargo.toml`, `snap/snapcraft.yaml` & `ubuntu-ppa/release.sh`
### Testing
Trippy is tested extensively in CI on Linux, Windows and macOS for every pull request. However, it is recommended to
test the release binaries on all platforms before release.
### GitHub Releases
- Tag the release with the version number `0.xx.0` and push the tag to GitHub:
```shell
git tag 0.xx.0
git push origin tag 0.xx.0
```
This will trigger the GitHub Actions workflow to build the release binaries and publish them to the GitHub release page.
- Edit GitHub release page and copy the relevant sections from `RELEASES.md` and `CHANGELOG.md`. Refer to previous
releases for the format.
### Crates.io
- Publish all crates to crates.io (in order):
```shell
cargo publish -p trippy-dns
cargo publish -p trippy-packet
cargo publish -p trippy-privilege
cargo publish -p trippy-core
cargo publish -p trippy-tui
cargo publish -p trippy
```
### Docker
From the repository root directory:
```shell
docker build . -t fujiapple/trippy:0.xx.0 -t fujiapple/trippy:latest
docker push fujiapple/trippy:0.xx.0
docker push fujiapple/trippy:latest
```
### Snapcraft
- Promote the first `0.xx.0` build to the `latest/stable` channel from the
Snapcraft [releases](https://snapcraft.io/trippy/releases) page
### WinGet
- Download the latest release Windows `zip` from
the [GitHub releases page](https://github.com/fujiapple852/trippy/releases/latest)
- Determine the SHA256 checksum of the release:
```shell
shasum -a 256 trippy-0.xx.0-x86_64-pc-windows-msvc.zip
```
- Update the `winget` [fork](https://github.com/fujiapple852/winget-pkgs) to the latest upstream
- Checkout the fork and create a branch called `fujiapple852-trippy-0.xx.0`
- Go to the Trippy directory
```shell
cd winget-pkgs/manifests/f/FujiApple/Trippy
```
- Copy the previous `0.yy.0` directory to a new directory for the new `0.xx.0` version
- Update the `PackageVersion`, `ReleaseDate` and update all paths to the new version
- Update the `InstallerSha256` with the checksum from the previous step
- Update the release notes from [CHANGELOG.md](https://github.com/fujiapple852/trippy/blob/master/CHANGELOG.md)
- Commit the changes with message:
```text
update fujiapple852/trippy to 0.xx.0
```
- Push the branch to the fork and create a pull request against the upstream `winget-pkgs` repository
### Ubuntu PPA
See the Ubuntu PPA [README.md](https://github.com/fujiapple852/trippy/blob/master/ubuntu-ppa/README.md)
## Help wanted
There are several the issues tagged
as [help wanted](https://github.com/fujiapple852/trippy/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) in the
GitHub issue tracker for which I would be especially grateful for assistance.
## License
This project is distributed under the terms of the Apache License (Version 2.0).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in time by you, as defined
in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
================================================
FILE: Cargo.toml
================================================
[workspace]
resolver = "2"
members = [
"crates/trippy",
"crates/trippy-tui",
"crates/trippy-core",
"crates/trippy-packet",
"crates/trippy-privilege",
"crates/trippy-dns",
"examples/*",
]
[workspace.package]
version = "0.14.0-dev"
authors = ["FujiApple <fujiapple852@gmail.com>"]
documentation = "https://github.com/fujiapple852/trippy"
homepage = "https://github.com/fujiapple852/trippy"
repository = "https://github.com/fujiapple852/trippy"
readme = "README.md"
license = "Apache-2.0"
edition = "2024"
rust-version = "1.85"
keywords = ["cli", "tui", "traceroute", "ping", "icmp"]
categories = ["command-line-utilities", "network-programming"]
[workspace.dependencies]
trippy-tui = { version = "0.14.0-dev", path = "crates/trippy-tui" }
trippy-core = { version = "0.14.0-dev", path = "crates/trippy-core" }
trippy-privilege = { version = "0.14.0-dev", path = "crates/trippy-privilege" }
trippy-dns = { version = "0.14.0-dev", path = "crates/trippy-dns" }
trippy-packet = { version = "0.14.0-dev", path = "crates/trippy-packet" }
anyhow = "1.0.91"
arrayvec = { version = "0.7.6", default-features = false }
bitflags = "2.11.0"
caps = "0.5.6"
chrono = { version = "0.4.44", default-features = false }
chrono-tz = "0.10.4"
clap = { version = "4.5.60", default-features = false }
clap-cargo = "0.15.2"
clap_complete = "4.6.0"
clap_mangen = "0.2.20"
comfy-table = { version = "7.1.4", default-features = false }
crossbeam = "0.8.4"
crossterm = { version = "0.28.1", default-features = false }
csv = "1.4.0"
derive_more = { version = "2.1.1", default-features = false }
dns-lookup = "3.0.1"
encoding_rs_io = "0.1.7"
etcetera = "0.10.0"
futures-concurrency = "7.6.3"
hex-literal = "1.1.0"
hickory-resolver = "0.24.4"
humantime = "2.3.0"
indexmap = { version = "2.13.0", default-features = false }
insta = "1.46.3"
itertools = "0.14.0"
maxminddb = "0.27.3"
mockall = "0.14.0"
nix = { version = "0.31.2", default-features = false }
parking_lot = "0.12.5"
paste = "1.0.15"
petgraph = "0.8.3"
pretty_assertions = "1.4.1"
rand = "0.10.0"
ratatui = "0.29.0"
serde = { version = "1.0.201", default-features = false }
serde_json = { version = "1.0.117", default-features = false }
serde_with = { version = "3.17.0", default-features = false, features = ["macros"] }
socket2 = "0.6.3"
strum = { version = "0.28.0", default-features = false }
sys-locale = "0.3.2"
test-case = "3.3.1"
thiserror = "2.0.3"
tokio = "1.50.0"
tokio-util = "0.7.18"
toml = { version = "1.0.7", default-features = false, features = ["serde"] }
tracing = "0.1.44"
tracing-chrome = "0.7.2"
tracing-subscriber = { version = "0.3.23", default-features = false }
tun-rs = "2.8.2"
unic-langid = "0.9.6"
unicode-width = "0.2.0"
widestring = "1.2.1"
windows-sys = "0.52.0"
[workspace.lints.rust]
unsafe_code = "deny"
rust_2018_idioms = { level = "warn", priority = -1 }
[workspace.lints.clippy]
all = { level = "warn", priority = -1 }
pedantic = { level = "warn", priority = -1 }
nursery = { level = "warn", priority = -1 }
module_name_repetitions = "allow"
option_if_let_else = "allow"
cast_possible_truncation = "allow"
missing_errors_doc = "allow"
cast_precision_loss = "allow"
bool_assert_comparison = "allow"
missing_const_for_fn = "allow"
struct_field_names = "allow"
cognitive_complexity = "allow"
[profile.release]
lto = true
================================================
FILE: Dockerfile
================================================
FROM rust:1.85 AS build-env
RUN rustup target add x86_64-unknown-linux-musl
WORKDIR /app
COPY Cargo.toml /app
COPY Cargo.lock /app
RUN mkdir -p /app/crates/trippy/src
RUN mkdir -p /app/crates/trippy-tui/src
RUN mkdir -p /app/crates/trippy-core/src
RUN mkdir -p /app/crates/trippy-dns/src
RUN mkdir -p /app/crates/trippy-packet/src
RUN mkdir -p /app/crates/trippy-privilege/src
COPY crates/trippy/Cargo.toml /app/crates/trippy/Cargo.toml
COPY crates/trippy-tui/Cargo.toml /app/crates/trippy-tui/Cargo.toml
COPY crates/trippy-core/Cargo.toml /app/crates/trippy-core/Cargo.toml
COPY crates/trippy-dns/Cargo.toml /app/crates/trippy-dns/Cargo.toml
COPY crates/trippy-packet/Cargo.toml /app/crates/trippy-packet/Cargo.toml
COPY crates/trippy-privilege/Cargo.toml /app/crates/trippy-privilege/Cargo.toml
COPY examples/ /app/examples/
# dummy build to cache dependencies
RUN echo "fn main() {}" > /app/crates/trippy/src/main.rs
RUN touch /app/crates/trippy-tui/src/lib.rs
RUN touch /app/crates/trippy-core/src/lib.rs
RUN touch /app/crates/trippy-dns/src/lib.rs
RUN touch /app/crates/trippy-packet/src/lib.rs
RUN touch /app/crates/trippy-privilege/src/lib.rs
RUN cargo build --release --target=x86_64-unknown-linux-musl --package trippy
# copy the actual application code and build
COPY crates/trippy/src /app/crates/trippy/src
COPY crates/trippy-tui/src /app/crates/trippy-tui/src
COPY crates/trippy-core/src /app/crates/trippy-core/src
COPY crates/trippy-dns/src /app/crates/trippy-dns/src
COPY crates/trippy-packet/src /app/crates/trippy-packet/src
COPY crates/trippy-privilege/src /app/crates/trippy-privilege/src
COPY crates/trippy-tui/build.rs /app/crates/trippy-tui
COPY crates/trippy-tui/locales.toml /app/crates/trippy-tui
COPY trippy-config-sample.toml /app
COPY trippy-config-sample.toml /app/crates/trippy-tui
COPY README.md /app
COPY README.md /app/crates/trippy
RUN cargo clean --release --target=x86_64-unknown-linux-musl -p trippy-tui -p trippy-core -p trippy-dns -p trippy-packet -p trippy-privilege
RUN cargo build --release --target=x86_64-unknown-linux-musl
FROM alpine
RUN apk update && apk add ncurses
COPY --from=build-env /app/target/x86_64-unknown-linux-musl/release/trip /
ENTRYPOINT ["./trip"]
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: README.md
================================================
<p align="center">
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/docs/src/assets/Trippy-Vertical-DarkMode.svg#gh-dark-mode-only" width="300">
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/docs/src/assets/Trippy-Vertical.svg#gh-light-mode-only" width="300"><br>
<br>
<a href="https://github.com/fujiapple852/trippy/actions/workflows/ci.yml">
<img src="https://github.com/fujiapple852/trippy/actions/workflows/ci.yml/badge.svg?branch=master"></a>
<a href="https://crates.io/crates/trippy/0.13.0">
<img src="https://img.shields.io/crates/v/trippy.svg"></a>
<a href="https://repology.org/project/trippy/versions">
<img src="https://repology.org/badge/tiny-repos/trippy.svg"></a>
<a href="https://trippy.zulipchat.com">
<img src="https://img.shields.io/badge/zulip-join_chat-brightgreen.svg"></a>
<a href="https://matrix.to/#/#trippy-dev:matrix.org">
<img src="https://img.shields.io/badge/matrix/trippy-dev:matrix.org-blue"></a>
<br>
<br>
Trippy combines the functionality of traceroute and ping and is designed to assist with the analysis of networking
issues.
</p>
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.12.0/demo.gif" alt="trippy"/>
## Quick Start
See the [getting started](https://trippy.rs/start/getting-started) guide.
### Install
Trippy runs on Linux, BSD, macOS, and Windows. It can be installed from most package managers, precompiled binaries, or
source.
For example, to install Trippy from `cargo`:
```shell
cargo install trippy --locked
```
<details>
<summary>All package managers</summary>
### Cargo
[](https://crates.io/crates/trippy/0.13.0)
```shell
cargo install trippy --locked
```
### APT (Debian)
[](https://tracker.debian.org/pkg/trippy)
```shell
apt install trippy
```
> ⓘ Note:
>
> Only available for Debian 13 (`trixie`) and later.
### PPA (Ubuntu)
[](https://launchpad.net/~fujiapple/+archive/ubuntu/trippy/+packages)
```shell
add-apt-repository ppa:fujiapple/trippy
apt update && apt install trippy
```
> ⓘ Note:
>
> Only available for Ubuntu 24.04 (`Noble`) and 22.04 (`Jammy`).
### Snap (Linux)
[](https://snapcraft.io/trippy)
```shell
snap install trippy
```
### Homebrew (macOS)
[](https://formulae.brew.sh/formula/trippy)
```shell
brew install trippy
```
### WinGet (Windows)
[](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/FujiApple/Trippy/0.13.0)
```shell
winget install trippy
```
### Scoop (Windows)
[](https://github.com/ScoopInstaller/Main/blob/master/bucket/trippy.json)
```shell
scoop install trippy
```
### Chocolatey (Windows)
[](https://community.chocolatey.org/packages/trippy)
```shell
choco install trippy
```
### NetBSD
[](https://pkgsrc.se/net/trippy)
```shell
pkgin install trippy
```
### FreeBSD
[](https://www.freshports.org/net/trippy/)
```shell
pkg install trippy
```
### OpenBSD
[](https://openports.pl/path/net/trippy)
```shell
pkg_add trippy
```
### Arch Linux
[](https://archlinux.org/packages/extra/x86_64/trippy)
```shell
pacman -S trippy
```
### Gentoo Linux
[](https://packages.gentoo.org/packages/net-analyzer/trippy)
```shell
emerge -av net-analyzer/trippy
```
### Void Linux
[](https://github.com/void-linux/void-packages/tree/master/srcpkgs/trippy)
```shell
xbps-install -S trippy
```
### ALT Sisyphus
[](https://packages.altlinux.org/en/sisyphus/srpms/trippy/)
```shell
apt-get install trippy
```
### Chimera Linux
[](https://github.com/chimera-linux/cports/tree/master/user/trippy)
```shell
apk add trippy
```
### Nix
[](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/tr/trippy/package.nix)
```shell
nix-env -iA trippy
```
### Docker
[](https://hub.docker.com/r/fujiapple/trippy/)
```shell
docker run -it fujiapple/trippy
```
### All Repositories
[](https://repology.org/project/trippy/versions)
</details>
See the [installation](https://trippy.rs/start/installation) guide for details of how to install Trippy on your system.
### Run
To run a basic trace to `example.com` with default settings, use the following command:
```shell
sudo trip example.com
```
See the [usage examples](https://trippy.rs/guides/usage) and [CLI reference](https://trippy.rs/reference/cli) for
details of how to use Trippy. To use Trippy without elevated privileges, see
the [privileges](https://trippy.rs/guides/privileges) guide.
## Documentation
Full documentation is available at [trippy.rs](https://trippy.rs).
<details>
<summary>documentation links</summary>
## Getting Started
See the [Getting Started](https://trippy.rs/start/getting-started/) guide.
## Features
See the [Features](https://trippy.rs/start/features/) list.
## Distributions
See the [Distributions](https://trippy.rs/start/installation/) list.
## Privileges
See the [Privileges](https://trippy.rs/guides/privileges/) guide.
## Usage Examples
See the [Usage Examples](https://trippy.rs/guides/usage/).
## Command Reference
See the [Command Reference](https://trippy.rs/reference/cli/).
## Theme Reference
See the [Theme Reference](https://trippy.rs/reference/theme/).
## Column Reference
See the [Column Reference](https://trippy.rs/reference/column/).
## Configuration Reference
See the [Configuration Reference](https://trippy.rs/reference/configuration/).
## Locale Reference
See the [Locale Reference](https://trippy.rs/reference/locale/).
## Versions
See the [Version Reference](https://trippy.rs/reference/version/).
## Frequently Asked Questions
### Why does Trippy show "Awaiting data..."?
See the [Awaiting Data](https://trippy.rs/guides/faq/) guide.
<a name="windows-defender"></a>
### How do I allow incoming ICMP traffic in the Windows Defender firewall?
See the [Windows Defender Firewall](https://trippy.rs/guides/windows_firewall/) guide.
### What are the recommended settings for Trippy?
See the [Recommended Tracing Settings](https://trippy.rs/guides/recommendation/) guide.
</details>
## Acknowledgements
Trippy is made possible by [ratatui](https://github.com/ratatui-org/ratatui) (
formerly [tui-rs](https://github.com/fdehau/tui-rs)),
[crossterm](https://github.com/crossterm-rs/crossterm) as well
as [several](https://github.com/fujiapple852/trippy/blob/master/Cargo.toml) foundational Rust libraries.
Trippy draws heavily from [mtr](https://github.com/traviscross/mtr) and also incorporates ideas
from both [libparistraceroute](https://github.com/libparistraceroute/libparistraceroute)
& [Dublin Traceroute](https://github.com/insomniacslk/dublin-traceroute).
The Trippy networking code is inspired by [pnet](https://github.com/libpnet/libpnet) and some elements of that codebase
are incorporated in Trippy.
The [AS][autonomous_system] data is retrieved from
the [IP to ASN Mapping Service](https://team-cymru.com/community-services/ip-asn-mapping/#dns) provided
by [Team Cymru](https://team-cymru.com).
The [trippy.cli.rs](https://trippy.cli.rs) CNAME hosting is provided by [cli.rs](https://cli.rs).
The Trippy chat room is sponsored by [Zulip](https://zulip.com).
Trippy logo designed by [Harun Ocaksiz Design](https://www.instagram.com/harunocaksiz).
## License
This project is distributed under the terms of the Apache License (Version 2.0).
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in time by you, as defined
in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
See [LICENSE](LICENSE) for details.
Copyright 2022 [Trippy Contributors](https://github.com/fujiapple852/trippy/graphs/contributors)
[autonomous_system]: https://en.wikipedia.org/wiki/Autonomous_system_(Internet)
================================================
FILE: RELEASES.md
================================================
# Release Notes
Release notes for Trippy 0.6.0 onwards. See also the [CHANGELOG](CHANGELOG.md).
# 0.13.0
## Highlights
The 0.13.0 release of Trippy includes several enhancements related to Type of Service (`ToS`) and adds new `Dscp` and
`Ecn` columns.
It also includes improvements to the TUI such as allowing a custom timezone to be set and adding the ability to read the
configuration file from the XDG app config directory. The `json` report has been enriched with start and end timestamps.
This release includes a number of bug fixes. For Windows users in particular, this release includes several important
stability improvements.
The release also introduces a new `system` address family option, which will become the new default in the next major
release.
Finally, Trippy now has a dedicated website and a logo!
### Type of Service (DSCP/ECN) Improvements
Trippy allows setting the Type of Service (`ToS`) for IPv4 via the `--tos` (`-Q`) command-line argument (or via the
configuration file). The `ToS` value is the second byte of the `IPv4` header and encodes the Differentiated Services
Code Point (`DSCP`) and Explicit Congestion Notification (`ECN`) fields.
Setting the `ToS` on outgoing probe packets can influence the Quality of Service (`QoS`) used by the network devices
along the path.
Probe responses received from the hops along the path include the `ToS` values in the Original Datagram (the `IPv4`/
`IPv6` header of the probe packet nested inside the `ICMP` error). Examining the `ToS` value from the Original Datagram
can provide useful insight into the `QoS` treatment of the probe packets by network devices along the path.
This release of Trippy adds two new columns to display the `DSCP` & `ECN` values, which are derived from the `ToS` value
from the Original Datagram for each hop. The new columns are:
- `Dscp` (`K`): The Differentiated Services Code Point (`DSCP`) of the Original Datagram for a hop
- `Ecn` (`M`): The Explicit Congestion Notification (`ECN`) of the Original Datagram for a hop
The `Dscp` and `Ecn` columns are decoded from the `ToS` field of the Original Datagram. If no `ToS` value is present,
then the columns will show `na`. Note that these columns show the most recent `ToS` value received from the hop and
may therefore change between rounds.
Well-known `DSCP` values are displayed as follows:
- Default Forwarding (`DF`) aka Best Effort aka Class Selector 0 (`CS0`)
- Assured Forwarding (`AFn`)
- Class Selector (`CSn`)
- High Priority Expedited Forwarding (`EF`)
- Voice Admit (`VA`)
- Lower Effort (`LE`)
Unknown `DSCP` values are displayed as a hexadecimal value.
The `ECN` value is displayed as follows:
- Not ECN-Capable Transport (`NotECT`)
- ECN Capable Transport(1) (`ECT1`)
- ECN Capable Transport(0) (`ECT0`)
- Congestion Experienced (`CE`)
These columns are hidden by default but can be enabled as needed. For more details, see
the [Column Reference](https://trippy.rs/reference/column).
The following example sets the `ToS` to be `224`, which is a `DSCP` value of `CS7` (0x38) and an `ECN` value of
`NotECT` (0x0), and enables the new columns:
```shell
trip example.com --tos 224 --tui-custom-columns holsravbwdtKM
```
The following screenshot shows the example trace:
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.13.0/dscp_ecn.png"/>
The `ToS` field of the Original Datagram has also been added to the `json` output format as a decimal value.
See [#1539](https://github.com/fujiapple852/trippy/issues/1539) for details.
This release also adds support for setting the `IPv6` Traffic Class (which encodes the `DSCP` & `ECN` values in the same
way as `IPv4`) via the same `--tos` (`-Q`) command-line argument (or via the configuration file). Note that setting the
`IPv6` Traffic Class is not currently supported on Windows.
See [#202](https://github.com/fujiapple852/trippy/issues/202) for details.
Finally, a bug which caused the `--tos` (`-Q`) command-line argument to be ignored for `IPv4/UDP` tracing has been
fixed in this release. See [#1540](https://github.com/fujiapple852/trippy/issues/1540) for details.
### Custom TUI Timezone
Trippy shows the wall-clock time in the header of the TUI. Currently, this is set to show the local timezone of the
system running Trippy. This can be problematic for users who are running Trippy in a container or on a remote system
that uses a different timezone.
This release adds the ability to set a custom timezone for the TUI using the `--tui-timezone` command-line argument (or
via the configuration file). The timezone can be set to any valid IANA timezone identifier, such as `UTC`,
`America/New_York`, or `Europe/London`.
The following example sets the timezone to `UTC`:
```shell
trip example.com --tui-timezone UTC
```
This can be made permanent by setting the `tui-timezone` value in the `tui` section of the configuration file:
```toml
[tui]
tui-timezone = "UTC"
```
See [#1513](https://github.com/fujiapple852/trippy/issues/1513) for details.
### XDG App Config Directory
Trippy will now attempt to locate a `trippy.toml` or `.trippy.toml` config file in the XDG app config directory
(i.e. `$XDG_CONFIG_HOME/trippy` or `~/.config/trippy`) in addition to existing locations.
This allows users to store their Trippy configuration files in a dedicated directory for Trippy, separate from other
applications.
The full list of locations Trippy will check for a `trippy.toml` or `.trippy.toml` config file is as
follows:
- the current directory
- the user home directory
- the XDG config directory (Unix only): `$XDG_CONFIG_HOME` or `~/.config`
- the XDG app config directory (Unix only): `$XDG_CONFIG_HOME/trippy` or `~/.config/trippy`
- the Windows data directory (Windows only): `%APPDATA%`
See [#1528](https://github.com/fujiapple852/trippy/issues/1528) for details.
### System Address Family
Trippy supports tracing for both `IPv4` and `IPv6` address families. If the tracing target is supplied as a hostname,
Trippy will attempt to resolve the hostname to a single `IPv4` or `IPv6` address. If the hostname resolves to both,
Trippy will use the address family (`--addr-family`) configuration to determine which address family
to use.
The possible values for `--addr-family` are:
- `ipv4` - Lookup IPv4 only
- `ipv6` - Lookup IPv6 only
- `ipv6-then-ipv4` - Lookup IPv6 with a fallback to IPv4
- `ipv4-then-ipv6` - Lookup IPv4 with a fallback to IPv6 [default]
The current default value for `--addr-family` is `ipv4-then-ipv6`, which means that if the hostname resolves to both
`IPv4` and `IPv6` addresses, Trippy will prefer the `IPv4` address family.
Some users find the default behavior undesirable, as it can lead to unexpected results when the hostname resolves to a
different address family than the one used by other applications on the system.
This release adds a new value for `--addr-family` called `system`. This value defers the choice of address family to the
first address returned by OS resolver. This means that if the hostname resolves to both `IPv4` and `IPv6` addresses, the
OS resolver will determine which address family to use based on the OS configuration.
Note that if the `--addr-family` value is set to `system` and the `--dns-resolve-method` is set to any value _other_
than `system` (i.e. `resolv`, `cloudflare` or `google`), then the address family lookup will effectively default to
`ipv6-then-ipv4`.
> **Important**: The default value for `--addr-family` will change to become `system` in the next major release of
> Trippy (0.14.0). This will be a breaking change for users who rely on the current default value of `ipv4-then-ipv6`.
See [#1469](https://github.com/fujiapple852/trippy/issues/1469) for details.
### Remove Address Family "downgrade" for Dublin Strategy
Currently, the address families `ipv4-then-ipv6` and `ipv6-then-ipv4` are silently _downgraded_ to `ipv4` when the
`dublin` ECMP strategy is used. This behaviour was previously necessary, as Trippy did not support the `dublin` ECMP
strategy for `IPv6`. However, Trippy has supported the `dublin` ECMP strategy for `IPv6` since version 0.10.0. As a
result, this release removes the address family _downgrade_ for the `dublin` ECMP strategy.
See [#1476](https://github.com/fujiapple852/trippy/issues/1476) for details.
### Windows Stability Improvements
This release includes several stability improvements for Windows. It fixes several known or potential issues that
could cause crashes or memory corruption. It is recommended that all Windows users upgrade to this release.
See the following issues for details:
- Memory corruption on Windows ([#1527](https://github.com/fujiapple852/trippy/issues/1527))
- Socket being closed twice on Windows ([#1443](https://github.com/fujiapple852/trippy/issues/1443))
- Potential crash on Windows for adapters without unicast
addresses ([#1547](https://github.com/fujiapple852/trippy/issues/1547))
- Potential use-after-free when discovering source address on
Windows ([#1558](https://github.com/fujiapple852/trippy/issues/1558))
### Start and End Timestamps in JSON report
The Trippy `json` report mode has been enhanced to show the start and end timestamps for the trace. These timestamps are
shown in UTC using RFC 3339 format.
The following example runs a trace to `example.com` for a single round and outputs the results in `json` format:
```shell
trip example.com -m json -C 1
```
The `info` section of the output now includes the `start_timestamp` and `end_timestamp` fields:
```json
{
"info": {
"target": {
"ip": "23.192.228.80",
"hostname": "example.com"
},
"start_timestamp": "2025-05-04T09:50:10.383221Z",
"end_timestamp": "2025-05-04T09:50:11.392039Z"
}
}
```
See [#1510](https://github.com/fujiapple852/trippy/issues/1510) for details.
### Reduce Tracing Verbosity
The `trippy-core` crate logging is overly verbose. This release reduces all `#[instrument]` annotations from the default
`info` level to the `trace` level. It also removes some tracing annotations and, in some cases, adds new ones.
There are now no `info` level logs and only a handful of `debug` level logs:
- Log the channel config when a channel is created (typically just once)
- Log the strategy config when the tracer is started (typically just once)
- Log each probe sent and received during a round (typically a handful per round)
For application users there is no change; however the default logging level (`--log-filter trippy=debug`) used when `-v`
is passed will now show substantially fewer logs. Users can set `--log-filter trippy=trace` to see a logging level
similar to the previous default.
See [#1482](https://github.com/fujiapple852/trippy/issues/1482) for details.
### Bug Fixes
This release fixes a bug where ICMP packets larger than 256 bytes could cause a tracer panic.
See [#1561](https://github.com/fujiapple852/trippy/issues/1561) for details.
It also adds a handful of missing configuration options to the settings dialog.
See [#1541](https://github.com/fujiapple852/trippy/issues/1541) for details.
### Trippy Website & Logo
Trippy now has a dedicated website: https://trippy.rs
The website is now the primary source of documentation. My thanks to @orhun for building the https://binsider.dev
website which I ~~took inspiration from~~ shamelessly copied for Trippy.
Along with the new website, Trippy (finally!) has a logo:
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/docs/src/assets/Trippy-Vertical-DarkMode.svg#gh-dark-mode-only" width="200">
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/docs/src/assets/Trippy-Vertical.svg#gh-light-mode-only" width="200"><br>
With thanks to [Harun Ocaksiz Design](https://www.instagram.com/harunocaksiz).
See [#100](https://github.com/fujiapple852/trippy/issues/100) for details.
### New Distribution Packages
Trippy has been added to the Void Linux package repository (with thanks to @icp1994!):
[](https://github.com/void-linux/void-packages/tree/master/srcpkgs/trippy)
```shell
xbps-install -S trippy
```
Trippy was also added to ALT Sisyphus package repository (with thanks
to [Aleksandr Voyt](https://packages.altlinux.org/en/sisyphus/maintainers/sobue)!)
[](https://packages.altlinux.org/en/sisyphus/srpms/trippy/)
```shell
apt-get install trippy
```
Finally, Trippy has been added to the Chimera Linux package repository (with thanks to @ttyyls!):
[](https://github.com/chimera-linux/cports/tree/master/user/trippy)
```shell
apk add trippy
```
### Thanks
My thanks to all Trippy contributors, package maintainers, translators and community members.
Feel free to drop by the Trippy Zulip room for a chat:
[](https://trippy.zulipchat.com/)
Happy Tracing!
# 0.12.2
## Highlights
This maintenance release of Trippy fixes a bug introduced in 0.12.0 which causes a tracer panic if `--first-ttl` is
set to be greater than one. The release also addresses a longstanding bug which causes `--dns-resolve-method resolv` to
ignore any value provided for `--addr-family` and therefore always use the default value of `ipv4`. Finally the help
text for `--addr-family` has been corrected.
See the main [0.12.0](https://github.com/fujiapple852/trippy/releases/tag/0.12.0) release note.
# 0.12.1
## Highlights
This maintenance release of Trippy fixes a bug which prevented translations from working in Docker and also divests all
internal use of `yaml` dependencies which were problematic to maintain on some platforms (thanks to @nc7s).
See the main [0.12.0](https://github.com/fujiapple852/trippy/releases/tag/0.12.0) release note.
# 0.12.0
## Highlights
The latest release of Trippy brings both cosmetic and functional improvements to the TUI, new columns, new distribution
packages, and a number of bug fixes.
The TUI has been updated to include a new _information bar_ at the bottom of the screen which allows for the header to
be shortened and simplified. The sample history chart has been enhanced to highlight missing probes and the presentation
of source and target addresses has also been simplified.
As well as these cosmetic changes, the TUI has gained support for internationalization (i18n) and the ability to
adjust the hop privacy setting dynamically.
This release introduces three new columns, which provide novel heuristics for measuring _forward loss_ and _backward
loss_, that are designed to assist users in interpreting the status of the trace.
Finally, this update includes new distribution packages for Debian and Ubuntu and addresses a number of bugs.
### TUI Information Bar
The TUI now includes an _information bar_ at the bottom of the screen, replacing the previous `Config` line in the
header. This change shortens the header by one line, optimizing space usage while keeping the overall vertical space of
the TUI unchanged.
The main TUI screen now appears as shown below (120x40 terminal size):
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.12.0/main_screen.png"/>
The left-hand side of the information bar displays a selection of static configuration items (in order):
- The address family and tracing protocol, e.g., `IPv4/ICMP`
- The privilege level, either `privileged` or `unprivileged`
- The locale, e.g., English (`en`), French (`fr`), etc.
The right-hand side of the information bar displays a selection of adjustable configuration items (in order):
- A toggle controlling whether `ASN` information is displayed (`□ ASN` for disabled, `■ ASN` for enabled)
- A toggle controlling whether hop detail mode is enabled (`□ detail` for disabled, `■ detail` for enabled)
- A toggle controlling whether hostnames, IP addresses, or both are displayed (`host`, `ip`, or `both`)
- The maximum `ttl` value for hop privacy, shown as `-` (privacy disabled) or a number (0, 1, 2, etc.)
- The maximum number of hosts displayed per hop, shown as `-` (automatic) or a number (1, 2, etc.)
In the above screenshot, the information bar indicates the trace is using `IPv4/ICMP`, is running in `privileged` mode,
the locale is English (`en`), `ASN` information is displayed, hop detail mode is disabled, hostnames are displayed, the
hop privacy maximum `ttl` is 2, and the maximum number of hosts per hop is set to automatic.
> **Note**: The information bar displays only a small number of important settings. All other settings can be viewed in
> the settings dialog, which can be opened by pressing `s` (default key binding).
The theme colors of the information bar can be customized using the `info-bar-bg-color` and `info-bar-text-color` theme
items. Refer to the [Theme Reference](https://github.com/fujiapple852/trippy#theme-reference) for more details.
Thanks to @c-git for their valuable feedback in refining the design of the information bar.
See [#1349](https://github.com/fujiapple852/trippy/issues/1349) for details.
### Sample History Missing Probes
Trippy displays a history of samples for each hop as a chart at the bottom of the TUI display. Each vertical line in the
chart corresponds to one sample, representing the value of the `Last` column.
Previously, if a probe was lost, the sample for that round would be shown as a blank vertical line. Starting with this
release, Trippy now highlights lost probes using a full vertical line in red (default theme color), making them easier
to identify.
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.12.0/lost_probes.png"/>
The theme color for regular samples can be configured using the existing `samples-chart-color` configuration option.
Additionally, the theme color for lost probes can now be customized using the new `samples-chart-lost-color`
configuration option. For more details, see
the [Theme Reference](https://github.com/fujiapple852/trippy#theme-reference).
See [#1247](https://github.com/fujiapple852/trippy/issues/1247) for further details.
### Source and Target Address Display Improvements
This release simplifies the display of the source and target addresses in the `Target` line in the header of the TUI.
The `Target` line has been updated such that, for both the source and destination addresses, the hostname is only shown
if it differs from the IP address.
For the destination address:
- If the user supplies a target hostname, it is resolved to an IP address, and both the IP address and the _provided_
hostname are shown.
- If the user supplies an IP address, a reverse DNS hostname lookup is attempted. If successful, both the IP address and
the _first resolved_ hostname are shown; otherwise, only the IP address is displayed.
For the source address:
- A reverse DNS hostname lookup is attempted. If successful, both the IP address and the _first resolved_ hostname are
shown; otherwise, only the IP address is displayed.
For example, when the user supplies an IP address as the tracing target, the `Target` line in the header is now shown as
follows:
```
Target: 192.168.1.21 -> 93.184.215.14 (example.com)
```
See [#1363](https://github.com/fujiapple852/trippy/issues/1363) for details.
### Adjustable Hop Privacy Mode Settings
Trippy includes a privacy feature designed to hide sensitive information, such as IP addresses and GeoIP data, for all
hops up to a configurable maximum `ttl` via the `tui-privacy-max-ttl` configuration option.
Previously, the privacy feature could only be toggled on or off within the TUI using the `toggle-privacy` command and
only if `tui-privacy-max-ttl` was configured _before_ Trippy was started.
In this release, the `toggle-privacy` command has been deprecated and replaced by two new TUI commands,
`expand-privacy` (bound to the `p` key by default) and `contract-privacy` (bound to the `o` key by default).
The `expand-privacy` command increases the `tui-privacy-max-ttl` value up to the maximum number of hops in the current
trace and the `contract-privacy` command decreases the `tui-privacy-max-ttl` value to the minimum value, which disables
privacy mode.
See [#1347](https://github.com/fujiapple852/trippy/issues/1347) for more details.
This release also repurposes the meaning of `tui-privacy-max-ttl` when set to `0`. Previously, a value of `0` indicated
that no hops should be hidden. Starting from this release, a value of `0` will indicate that the source of the trace, as
shown in the `Target` line of the header, should be hidden.
Values of `1` or greater retain their existing behavior but will now also hide the source of the trace in addition to
the specified number of hops.
As a result of this change, the default value for `tui-privacy-max-ttl` has been updated:
- If not explicitly set (via a command-line argument or the configuration file), nothing will be hidden by default.
- If explicitly set to `0` (the previous default), the source of the trace will be hidden.
See [#1365](https://github.com/fujiapple852/trippy/issues/1365) for details.
### Preserve Screen on Exit
Trippy previously supported the `--tui-preserve-screen` command-line flag, which could be used to prevent the terminal
screen from being cleared when Trippy exits. This feature is useful for users who wish to review trace results after
exiting the application. However, the flag had to be set before starting Trippy and could not be toggled during a trace.
This release introduces the `quit-preserve-screen` TUI command (bound to the `shift+q` key by default). This command
allows users to quit Trippy without clearing the terminal screen, regardless of whether the `--tui-preserve-screen` flag
is set.
See [#1382](https://github.com/fujiapple852/trippy/issues/1382) for details.
### TUI Internationalization (i18n)
The Trippy TUI has been translated into multiple languages. This includes all text displayed in the TUI across all
screens and dialogs, as well as GeoIP location data shown on the world map.
The TUI will automatically detect the system locale and use the corresponding translations if available. The locale can
be overridden using the `--tui-locale` configuration option.
Locales can be specified for a language or a combination of language and region. For example a general locale can be
created for English (`en`) and specific regional locales can be created, such as United Kingdom English (`en-UK`) and
United States English (`en-US`).
If the user's chosen full locale (`language-region`) is not available, Trippy will fall back to using the locale for the
language only, if it exists. For example if the user sets the locale to `en-AU`, which is not currently defined in
Trippy, it will fall back to the `en` locale, which is defined.
If the user's chosen locale does not exist at all, Trippy will fall back to English (`en`).
Locales are generally added for the language only unless there is a specific need for region-based translations.
Some caveats to be aware of:
- The configuration file, command-line options, and most error messages are not translated.
- Many common abbreviated technical terms, such as `IPv4` and `ASN`, are not translated.
The following example sets the TUI locale to be Chinese (`zh`):
```shell
trip example.com --tui-locale zh
```
This can be made permanent by setting the `tui-locale` value in the `tui` section of the configuration file:
```toml
[tui]
tui-locale = "zh"
```
The following screenshot shows the TUI with the locale set to Chinese (`zh`):
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.12.0/help_screen_zh.png"/>
The list of available locales can be printed using the `--print-locales` flag:
```shell
trip --print-locales
```
As of this release, the following locales are available:
- Chinese (`zh`)
- English (`en`)
- French (`fr`)
- German (`de`)
- Italian (`it`)
- Portuguese (`pt`)
- Russian (`ru`)
- Spanish (`es`)
- Swedish (`sv`)
- Turkish (`tr`)
See [#1319](https://github.com/fujiapple852/trippy/issues/1319), [#1357](https://github.com/fujiapple852/trippy/issues/1357), [#1336](https://github.com/fujiapple852/trippy/issues/1336)
and the [Locale Reference](https://github.com/fujiapple852/trippy#locale-reference) for more details.
Corrections to existing translations or the addition of new translations are always welcome. See
the [tracking issue](https://github.com/fujiapple852/trippy/issues/506) for the status of each translation and details
on how to contribute.
Adding these translations has been a significant effort and I would like to express a huge _thank you_ (谢谢! Merci!
Danke! Grazie! Obrigado! Спасибо! Gracias! Tack! Teşekkürler!) to @0323pin, @arda-guler, @histrio, @josueBarretogit,
@one, @orhun, @peshay, @ricott1, @sxyazi, @ulissesf, and @zarkdav for all of their time and effort adding and reviewing
translations for this release.
### Forward and Backward Packet Loss Heuristics
In line with most classic traceroute tools, Trippy displays the number of probes sent (`Snd`), received (`Recv`), and a
loss percentage (`Loss%`) for each hop. However, many routers are configured to rate-limit or even drop ICMP traffic.
This can lead to false positives for packet loss, particularly for intermediate hops, as the lack of a response from
such hops does not typically indicate genuine packet loss. This is a common source of confusion for users interpreting
trace results.
Trippy already provides a color-coded status column (`Sts`), that considers both packet loss percentage and whether the
hop is the target of the trace, to try and assist users in interpreting the status of each hop. While this feature is
helpful, it does not make it clear _why_ a hop has a particular status nor help users interpret the overall status of
the trace.
To further assist users, this release of Trippy introduces a pair of novel heuristics to measure _forward loss_ and
_backward loss_. Informally, _forward loss_ indicates whether the loss of a probe is the _cause_ of subsequent losses
and _backward loss_ indicates whether the loss of a probe is the _result_ of a prior loss on the path.
More precisely:
- _forward loss_ for probe `P` in round `R` occurs when probe `P` is lost in round `R` and _all_ subsequent probes
within round `R` are also lost.
- _backward loss_ for probe `P` in round `R` occurs when probe `P` is lost in round `R` and _any_ prior probe within
round `R` has _forward loss_.
These heuristics are encoded in three new columns:
- `Floss` (`F`): The number of probes with _forward loss_
- `Bloss` (`B`): The number of probes with _backward loss_
- `Floss%` (`D`): The percentage of probes with _forward loss_
These columns are hidden by default but can be enabled as needed. For more details, see
the [Column Reference](https://github.com/fujiapple852/trippy#column-reference).
The following screenshot shows an example trace with the new columns enabled:
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.12.0/floss_bloss.png"/>
In the following (contrived) example, after initially discovering the target (`10.0.0.105`) during the first round,
genuine packet loss occurs in _all_ subsequent rounds at the third hop. This means that no probes on the common path are
able to get beyond the third hop.
```
╭Hops───────────────────────────────────────────────────────────────╮
│# Host Loss% Snd Recv Floss Bloss Floss% │
│1 10.0.0.101 0.0% 96 96 0 0 0.0% │
│2 10.0.0.102 0.0% 96 96 0 0 0.0% │
│3 No response 100.0% 96 0 95 0 98.9% │
│4 No response 100.0% 96 0 0 95 0.0% │
│5 10.0.0.105 99.0% 96 1 0 95 0.0% │
```
From this we can determine that the loss at the third hop is classified as _forward loss_ because all subsequent
probes (4th and 5th) in the same round are also lost. We can also conclude that the 4th and 5th hops have _backward
loss_ starting from round two, as in those rounds a prior hop (the third hop) has _forward loss_.
Note the difference between the traditional `Loss%` column and the new `Floss%` column. The `Loss%` column indicates
packet loss at several hops (3rd, 4th, and 5th). In contrast, the `Floss%` column helps us determine that the true
packet loss most likely occurs at the 3rd hop.
It is important to stress that this technique is a _heuristic_, and both _false positives_ and _false negatives_ are
possible. Some specific caveats to be aware of include:
- Every probe sent in every round is an _independent trial_, meaning there is no guarantee that all probes within a
given round will follow the same path (or "flow"). The concept of "forward loss" and "backward loss" assumes that all
probes followed a single path. This assumption is typically met (but not guaranteed) when using tracing strategies
such as ICMP, UDP/Dublin, or UDP/Paris.
- Any given host on the path may drop packets for only a subset of probes sent within a round, either due to rate
limiting or genuine intermittent packet loss. This could result in a false positive for "forward loss" at a given hop
if all subsequent hops in the round exhibit packet loss that is not genuine. For example, in the scenario above, the
hop with `ttl=3` could be incorrectly deemed to have "forward loss" if observed loss from hops `ttl=4` and `ttl=5` is
not genuine (e.g., caused by rate-limiting).
- A false positive for "backward loss" could occur at a hop experiencing genuine packet loss if a previous hop on the
path has "forward loss" that is not genuine. In the scenario above, if the hop with `ttl=4` has genuine packet loss,
it will still be marked with "backward loss" due to the "forward loss" at `ttl=3`.
Despite these caveats, the addition of _forward loss_ and _backward loss_ heuristics aims to help users more accurately
interpret trace outputs. However, these heuristics should be considered experimental and may be subject to change in
future releases.
See [#860](https://github.com/fujiapple852/trippy/issues/860) for details.
### Bug Fixes
The previous release of Trippy introduced a bug ([#1290](https://github.com/fujiapple852/trippy/issues/1290)) that
caused reverse DNS lookups to be enqueued multiple times when the `dns-ttl` expired, potentially leading to the hostname
being displayed as `Timeout: xxx` for a brief period.
A long-standing bug ([#1398](https://github.com/fujiapple852/trippy/issues/1398)) which caused the TUI sample history
and frequency charts to ignore sub-millisecond samples has been fixed.
This release fixes a bug ([#1287](https://github.com/fujiapple852/trippy/issues/1287)) that caused the tracer to panic
when parsing certain ICMP extensions with malformed lengths.
It also resolves an issue ([#1289](https://github.com/fujiapple852/trippy/issues/1289)) where the ICMP extensions mode
was not being displayed in the TUI settings dialog.
A bug ([#1375](https://github.com/fujiapple852/trippy/issues/1375)) that caused the cursor to not move to the bottom of
the screen when exiting while preserving the screen has also been fixed.
Finally, this release fixes a bug ([#1327](https://github.com/fujiapple852/trippy/issues/1327)) that caused Trippy to
incorrectly reject the value `ip` for the `tui-address-mode` configuration option (thanks to @c-git).
### New Distribution Packages
Trippy is now available in Debian 13 (`trixie`) and later (with thanks to @nc7s!).
[](https://tracker.debian.org/pkg/trippy)
```shell
apt install trippy
```
See ([#1312](https://github.com/fujiapple852/trippy/issues/1312)) for details.
The official Trippy PPA for Ubuntu is now also available for the `noble` distribution.
[](https://launchpad.net/~fujiapple/+archive/ubuntu/trippy/+packages)
```shell
sudo add-apt-repository ppa:fujiapple/trippy
sudo apt update && apt install trippy
```
See ([#1308](https://github.com/fujiapple852/trippy/issues/1308)) for details.
You can find the full list of [distributions](https://github.com/fujiapple852/trippy/tree/master#distributions) in the
documentation.
### Thanks
My thanks to all Trippy contributors, package maintainers, translators and community members.
Feel free to drop by the Trippy Zulip room for a chat:
[](https://trippy.zulipchat.com/)
Happy Tracing!
# 0.11.0
## Highlights
This release of Trippy adds NAT detection for IPv4/UDP/Dublin tracing, a new public API, reverse DNS lookup cache
time-to-live, transient error handling for IPv4, a new ROFF manual page generator, several new columns, improved error
messages and a revamped help dialog with settings tab hotkeys.
There are two breaking changes, a new initial sequence number is used which impacts the default behavior of UDP tracing
and two configuration fields have been renamed and moved.
Finally, there are a handful of bug fixes and two new distribution packages, Chocolatey for Windows and an official PPA
for Ubuntu and Debian based distributions.
### NAT Detection for IPv4/UDP/Dublin
When tracing with the Dublin tracing strategy for IPv4/UDP, Trippy can now detect the presence of NAT (Network Address
Translation) devices on the path.
[RFC 3022 section 4.3](https://datatracker.ietf.org/doc/html/rfc3022#section-4.3) requires that "NAT to be completely
transparent to the host" however in practice some fully compliant NAT devices leave behind a telltale sign that Trippy
can use.
Trippy will indicate if a NAT device has been detected by adding `[NAT]` at the end of the hostname. There is also a
new (hidden by default) column, `Nat`, which can be enabled to show the NAT status per hop.
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.11.0/nat_detection.png"/>
NAT devices are detected by observing a difference in the _expected_ and _actual_ checksum of the UDP packet that is
returned as the part of the Original Datagram in the ICMP Time Exceeded message. If they differ then it indicates that a
NAT device has modified the packet. This happens because the NAT device must recalculate the UDP checksum after
modifying the packet (i.e. translating the source port) and so the checksum in the UDP packet that is nested in the ICMP
error may not, depending on the device, match the original checksum.
To help illustrate the technique, consider sending the following IPv4/UDP packet (note the UDP `Checksum B` here):
```
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
|Version| IHL |Type of Service| Total Length | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Identification |Flags| Fragment Offset | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Time to Live | Protocol | Checksum A | │ IPv4 Header
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Source Address | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Destination Address | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Source Port | Destination Port | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ UDP Header
| Length | Checksum B | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
```
Trippy expect to receive an IPv4/ICMP `TimeExceeded` (or other) error which contains the Original Datagram (OD) IPv4/UDP
packet that was sent above with `Checksum B'` in the Original Datagram (OD) IPv4/UDP packet:
```
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
|Version| IHL |Type of Service| Total Length | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Identification |Flags| Fragment Offset | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Time to Live | Protocol | Checksum C | │ IPv4 Header
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Source Address | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Destination Address | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
| Type | Code | Checksum D | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ IPv4 Payload (ICMP TE Header)
| Unused | │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │
│
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
|Version| IHL |Type of Service| Total Length | │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
| Identification |Flags| Fragment Offset | │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
| Time to Live | Protocol | Checksum A' | │ │ ICMP TE Payload (OD IPv4 Header)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
| Source Address | │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
| Destination Address | │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │
│ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │ │
| Source Port | Destination Port | │ │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │ │ OD IPv4 Payload (UDP header)
| Length | Checksum B' | │ │ │
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ │ │ │
```
If `Checksum B'` in the UDP packet nested in the ICMP error does not match `Checksum B` in the UDP packet that was sent
then Trippy can infer that a NAT device is present.
This technique allows for the detection of NAT at the first hop. To detect multiple NAT devices along the path, Trippy
must also check for _changes_ in the observed checksum between consecutive hops, as changes to the UDP checksum will "
carry forward" to subsequent hops. This requires taking care to account for hops that do not respond. This is only
possible when using the Dublin tracing strategy, as it does not modify the UDP header per probe; therefore, the
checksums are expected to remain constant, allowing changes in the checksum between hops to be detected.
Note that this method cannot detect all types of NAT devices and so should be used in conjunction with other methods
where possible.
See the [issue](https://github.com/fujiapple852/trippy/issues/1104) for more details.
### Public API
Trippy has been designed primarily as a standalone _tool_, however it is built on top of a number of useful libraries,
such as the core tracer, DNS resolver and more. These libraries have always existed but were tightly integrated into the
tool and were not designed for use by third party crates.
This release introduces the Trippy public API which can be used to build custom tools on top of the Trippy libraries.
The full set of libraries exposed is:
| Crate | Description |
| ---------------------------------------------------- | ---------------------------------------------------- |
| [trippy](https://docs.rs/trippy) | Common entrypoint crate |
| [trippy-core](https://docs.rs/trippy-core) | The core Trippy tracing functionality |
| [trippy-packet](https://docs.rs/trippy-packet) | Packet wire formats and packet parsing functionality |
| [trippy-dns](https://docs.rs/trippy-dns) | Perform forward and reverse lazy DNS resolution |
| [trippy-privilege](https://docs.rs/trippy-privilege) | Discover platform privileges |
| [trippy-tui](https://docs.rs/trippy-tui) | The Trippy terminal user interface |
To use the Trippy public API you should add the common entrypoint `trippy` crate to your `Cargo.toml` file and then
enable the desired features. Note that the `trippy` crate includes `tui` as a default feature and so you should disable
default features when using it as a library. Alternatively, it is also possible to add the crates individually.
For example, to use the core Trippy tracing functionality you would add the `trippy` crate, disable default features and
enable the `core` feature:
```toml
[dependencies]
trippy = { version = "0.11.0", default-features = false, features = ["core"] }
```
The `hello-world` example below demonstrates how to use the Trippy public API to perform a simple trace and print the
results of each round:
```rust
use std::str::FromStr;
use trippy::core::Builder;
fn main() -> anyhow::Result<()> {
let addr = std::net::IpAddr::from_str("1.1.1.1")?;
Builder::new(addr)
.build()?
.run_with(|round| println!("{:?}", round))?;
Ok(())
}
```
Whilst Trippy adheres to [Semantic Versioning](https://semver.org/), the public API is not yet considered stable and may
change in future releases.
See [crates](crates/README.md) and the usage [examples](examples/README.md) for more information.
### New Initial Sequence
For UDP tracing, by default, Trippy uses a fixed source port and a variable destination port which is set from the
sequence number, starting from an initial sequence of 33000 and incremented for each probe, eventually wrapping around.
By [convention](https://en.wikipedia.org/wiki/List_of_TCP_and_UDP_port_numbers), many devices on the internet allow UDP
probes to ports in the range 33434..=33534 and will return a `DestinationUnreachable` ICMP error, which can be used to
confirm that the target has been reached. Since Trippy does not use destination ports in this range for UDP probes by
default, the target host will typically not respond with an ICMP error, and so Trippy cannot know that the target was
reached, and must therefore show the hop as unknown.
Another issue with this default setup is that the sequence number will eventually enter the range 33434..=33534 at which
point the target will _begin_ to respond with the `DestinationUnreachable` ICMP error. However, there is no guarantee
that the probe sent for sequence 33434 (i.e., the first one for which the target host will be able to respond) will be
for the minimum time-to-live (ttl) required to reach the target. This leads to confusing output, which is hard for users
to interpret. See [issue](https://github.com/fujiapple852/trippy/issues/1203) for more details.
These issues can be avoided today, either by changing the initial sequence number to be in the range 33434..=33534 by
setting the `--initial-sequence` flag or by using a fixed destination port (and therefore a variable source port) in the
same range by setting the `--target-port` flag.
In the following example, the initial sequence number is set to 33434:
```shell
trip example.com --udp --initial-sequence 33434
```
This can be made permanent by setting the `initial-sequence` value in the `strategy` section of the configuration file:
```toml
[strategy]
initial-sequence = 33434
```
In the following example, the destination port is set to 33434:
```shell
trip example.com --udp --target-port 33434
```
This can be made permanent by setting the `target-port` value in the `strategy` section of the configuration file:
```toml
[strategy]
target-port = 33434
```
As the default behavior in Trippy leads to these confusing issues, this release modifies the default sequence number to
be 33434. This is a **breaking change** and will impact users who rely on the old default initial sequence number.
This change introduces a new problem, albeit a lesser one: UDP traces will now begin with a destination port of 33434
and so `DestinationUnreachable` ICMP errors will typically be returned by the target immediately. However, eventually
the sequence number will move _beyond_ the range 33434..=33534 and so the target host will _stop_ responding
with `DestinationUnreachable` ICMP errors. This leads to the appearance that the target has started dropping packets.
While this is technically correct, this is not desirable behavior as the target has not really disappeared.
It is therefore recommended to _always_ fix the `target-port` to be in the range 33434..=33534 for UDP tracing and allow
the source port to vary instead. This may become the default behavior for UDP tracing in a future release; that would
represent a significant difference in default behavior compared to most traditional Unix traceroute tools, which vary
the destination port by default.
### Reverse DNS Lookup Cache Time-to-live
Trippy performs a reverse DNS lookup for each host encountered during the trace and the resulting hostnames are cached
indefinitely. This can lead to stale hostnames being displayed in the TUI if they change after the trace has begun.
Note that the DNS cache can be flushed manually by pressing `ctrl+k` (default key binding) in the TUI.
Starting from this release, the reverse DNS cache can be configured to expire after a certain time to live. By default
this is set to be 5 minutes (300 seconds) and can be configured using the `--dns-ttl` flag or the `dns-ttl`
configuration option.
The following example sets the DNS cache time-to-live to 30 seconds:
```shell
trip example.com --dns-ttl 30s
```
This can be made permanent by setting the `dns-ttl` value in the `dns` section of the configuration file:
```toml
[dns]
dns-ttl = "30s"
```
### Transient Error Handling for IPv4
Trippy records the number of probes sent and the number of probes received for each hop and uses this information to
calculate packet loss. Any probe that is _successfully_ sent for which no response is received is considered lost.
Currently, if a probe cannot be sent for any reason, then Trippy will crash and show a BSOD. This is not typically an
issue, as such failures imply a local issue with the host network configuration rather than an issue with the target or
any intermediate hops.
However, it is possible that a probe may fail to send for a transient reason, such as a temporary local host issue, and
so it would be useful to be able to handle such errors gracefully. A common example would be running Trippy on a host
and during the trace disabling the network interface.
Starting from this release, Trippy will continue the trace even if a probe fails to send and will instead show a warning
to the user in the TUI about the number of probe failures. A new column (hidden by default), `Fail`, has also been added
to the TUI to show the number of probes that failed to send for each hop.
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.11.0/fails.png"/>
This has been implemented for macOS, Linux and Windows for IPv4 only. Support for IPv6 and other platforms will be added
in future releases.
See the [tracking issue](https://github.com/fujiapple852/trippy/issues/1238) for more details.
### Generate ROFF Man Page
Trippy can now generate manual pages in ROFF format. This can be useful for users who wish to install Trippy on systems
which do not have a package manager or for users who wish to install Trippy from source. It can also be used by package
maintainers to generate manual pages for their distribution.
The following command generates a ROFF manual page for Trippy:
```shell
trip --generate-man > /path/to/man/pages/trip.1
```
### New Columns
This release introduced several new columns, all of which are hidden by default. These are:
- `Type`: The ICMP packet type for the last probe for the hop
- `Code`: The ICMP packet code for the last probe for the hop
- `Nat`: The NAT detection status for the hop
- `Fail`: The number of probes which failed to send for the hop
The following shows the `Type` and `Code` columns:
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.11.0/type_code_columns.png"/>
See the [Column Reference](https://github.com/fujiapple852/trippy#column-reference) for a full list of all available
columns.
### Settings Dialog Tab Hotkeys
The settings dialog can be accessed by pressing `s` (default key binding) and users can navigate between the tabs using
the left and right arrow keys (default key bindings). This release introduces hotkeys to allow users to jump directly to
a specific tab by pressing `1`-`7` (default key bindings).
See the [Key Bindings Reference](https://github.com/fujiapple852/trippy#key-bindings-reference) for details.
### Help Dialog Revamped
The existing Trippy help dialog shows a hardcoded list of key bindings which may not reflect the actual key bindings the
user has configured. Trippy shows the correct key bindings in the settings dialog which can be accessed by
pressing `s` (default key binding) and navigating to the Bindings tab. Therefore, the key bindings in the help dialog
are both potentially incorrect and redundant.
This release revamps the help dialog and includes instructions on how to access the key bindings from the settings
dialog as well as some other useful information.
<img width="60%" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.11.0/new_help_dialog.png"/>
### Improved Error Messages
Error reporting has been improved for parameters such as `--min-round-duration` (`-i`). Previously, if an invalid
duration was provided, the following error would be reported:
```shell
$ trip example.com -i 0.05
Error: invalid character at 1
```
Starting from this release, such error will instead be shown as:
```shell
$ trip example.com -i 0.05
error: invalid value '0.05' for '--min-round-duration <MIN_ROUND_DURATION>': expected time unit (i.e. 100ms, 2s, 1000us)
For more information, try '--help'.
```
This covers all "duration" parameters, namely:
- `min_round_duration`
- `max_round_duration`
- `grace_duration`
- `read_timeout`
- `dns_timeout`
- `tui_refresh_rate`
### Renamed Configuration
The following configuration fields have been renamed and moved from the `[tui]` to the `[strategy]` section in the
configuration file:
- `tui-max-samples` -> `max-samples`
- `tui-max-flows` -> `max-flows`
This is a **breaking change**. Attempting to use the legacy field names will result in an error pointing to the new
name.
The following example shows the error reported if the old names are used from the command line:
```shell
error: unexpected argument '--tui-max-samples' found
tip: a similar argument exists: '--max-samples'
```
The following examples shows the error reported if the ld names are used from the configuration file:
```shell
Error: tui-max-samples in [tui] section is deprecated, use max-samples in [strategy] section instead
```
### Bug Fixes
This release fixes a bug where `DestinationUnreachable` ICMP errors were assumed to have been sent by the target host,
whereas they may also be sent by an intermediate hop.
Another fix addresses an issue where the TUI would calculate the maximum number of hops to display based on the maximum
observed across all rounds rather than for the latest round.
Finally, a minor bug was fixed where `AddressInUse` and `AddrNotAvailable` errors were being conflated.
### New Distribution Packages
Trippy has been added to the Chocolatey community repository (with thanks to @Aurocosh!):
[](https://community.chocolatey.org/packages/trippy)
```shell
choco install trippy
```
Trippy also has an official PPA for Ubuntu and Debian based distributions (with thanks to @zarkdav!):
[](https://launchpad.net/~fujiapple/+archive/ubuntu/trippy/+packages)
```shell
sudo add-apt-repository ppa:fujiapple/trippy
sudo apt update && apt install trippy
```
You can find the full list of [distributions](https://github.com/fujiapple852/trippy/tree/master#distributions) in the
documentation.
### Thanks
My thanks to all Trippy contributors, package maintainers and community members.
Feel free to drop by the new Trippy Zulip room for a chat:
[](https://trippy.zulipchat.com/)
Happy Tracing!
# 0.10.0
## Highlights
The first release of 2024 is packed with new features, such as customizable columns, jitter calculations, Dublin tracing
strategy for IPv6/UDP, support for IPinfo GeoIp files, enhanced DNS resolution with IPv6/IPv4 fallback and CSS named
colors for the TUI as well as a number of bug fixes. Since the last release there has also been a significant
improvement in automated testing, notably the introduction of TUN based simulation testing for IPv4.
### Customize Columns
#### Customize Columns in TUI
It is now possible to customize which columns are shown in the TUI and to adjust the order in which they are displayed.
This customization can be made from within the TUI or via configuration.
To customize the columns from the TUI you must open the settings dialog (`s` key) and navigating to the new `Columns`
tab (left and right arrow keys). From this tab you can select the desired column (up and down arrow keys) and toggle the
column visibility on and off (`c` key) or move it left (`,` key) or right (`.` key) in the list of columns.
<img width="60%" alt="columns" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.10.0/columns_settings.png">
You can supply the full list of columns, in the desired order, using the new `--tui-custom-columns` command line
argument. The following example specifies the standard list of columns in the default order:
```shell
trip example.com --tui-custom-columns holsravbwdt
```
Alternatively, to make the changes permanent you may add the `tui-custom-columns` entry to the `tui` section of the
Trippy configuration file:
```toml
[tui]
tui-custom-columns = "holsravbwdt"
```
Note that the value of `tui-custom-columns` can be seen in the corresponding field of the `Tui` tab of the settings
dialog and will reflect any changes made to the column order and visibility via the Tui. This can be useful as you may
copy this value and use it in the configuration file directly.
<img width="60%" alt="tui-custom-columns" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.10.0/tui_settings.png">
#### New Columns
This release also introduced several new columns, all of which are hidden by default. These are:
- Last source port: The source port for last probe for the hop
- Last destination port: The destination port for last probe for the hop
- Last sequence number: The sequence number for the last probe for the hop
- Jitter columns: see the "Calculate and Display Jitter" section below
See the [Column Reference](https://github.com/fujiapple852/trippy#column-reference) for a full list of all available
columns.
#### Column Layout Improvement
The column layout algorithm used in the hop table has been improved to allow the maximum possible space for the `Host`
column. The width of the `Host` column is now calculated dynamically based on the terminal width and the set of columns
currently configured.
### Calculate and Display Jitter
Trippy can now calculate and display a variety of measurements related to _jitter_ for each hop. Jitter is a measurement
of the difference in round trip time between consecutive probes. Specifically, the following new calculated values are
available in Trippy `0.10.0`:
- Jitter: The round-trip-time (RTT) difference between consecutive rounds for the hop
- Average Jitter: The average jitter of all probes for the hop
- Maximum Jitter: The maximum jitter of all probes for the hop
- Inter-arrival Jitter: The smoothed jitter value of all probes for the hop
These values are always calculated and are included in the `json` report. These may also be displayed as columns in the
TUI, however they are not shown by default. To enabled these columns in the TUI, please see
the [Column Reference](https://github.com/fujiapple852/trippy#column-reference).
<img width="60%" alt="jitter" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.10.0/jitter_columns.png">
### Dublin Tracing Strategy for IPv6/UDP
The addition of support for the [dublin](https://github.com/insomniacslk/dublin-traceroute) tracing strategy for
IPv6/UDP marks the completion of a multi-release journey to provide support for both Dublin
and [paris](https://github.com/libparistraceroute/libparistraceroute/wiki/Checksum) tracing strategies for both IPv4/UDP
and IPv6/UDP.
As a reminder, unlike classic traceroute and MTR, these alternative tracing strategies do not encode the probe sequence
number in either the src or dest port of the UDP packet, but instead use other protocol and address family specific
techniques. Specifically, the Dublin tracing strategy for IPv6/UDP varies the length of the UDP payload for this
purpose.
By doing so, these strategies are able to keep the src and dest ports fixed which makes it much more likely (though not
guaranteed) that each round of tracing will follow the same path through the network (note that this is not true for the
return path).
The following command runs an IPv6/UDP trace using the Dublin tracing strategy with fixed src and dest ports:
```shell
trip example.com --udp -6 -R dublin -S 5000 -P 3500
```
Note that, for both Paris and Dublin tracing strategies, if you fix either the src or dest ports (but _not_ both) then
Trippy will vary the unfixed port _per round_ rather than _per hop_. This has the effect that all probes _within_ a
round will likely follow the same network path but probes _between_ round will follow different paths. This can be
useful in conjunction with flows (`f` key) to visualize the various paths packet flow through the network. See
this [issue](https://github.com/fujiapple852/trippy/issues/1007) for more details.
<img width="60%" alt="ipv6_dublin" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.10.0/dublin_ipv6_src_dest_seq_columns.png">
With UDP support for the Paris and Dublin tracing strategies now complete, what remains is adding support for these for
the TCP protocol. Refer to the [ECMP tracking issue](https://github.com/fujiapple852/trippy/issues/274) for details.
### IPinfo GeoIp Provider
Trippy currently supports the ability to lookup and display GeoIp information from MMDB files, but prior to `0.10.0`
only the [MaxMind](https://www.maxmind.com) "GeoLite2 City" (and lite) MMDB files were supported. This release
introduces support for the "IP to Country + ASN Database" and "IP to Geolocation Extended Database" MMDB files
from [IPinfo](https://ipinfo.io).
The "IP to Country + ASN Database" MMDB file provided by IPinfo can be used as follows:
```shell
trip example.com --geoip-mmdb-file /path/to/country_asn.mmdb --tui-geoip-mode short
```
These settings can be made permanent by setting the following values in the `tui` section of the configuration file:
```toml
[tui]
geoip-mmdb-file = "/path/to/country_asn.mmdb"
tui-geoip-mode = "short"
```
### Enhanced DNS Resolution with IPv4/IPv6 Fallback
When provided with a DNS name such as `example.com` Trippy tries to resolve it to an IPv4 or an IPv6 address and fails
if no such IP exists for the configured `addr-family` mode, which must be either IPv4 or IPv6.
Starting from version `0.10.0`, Trippy can be configured to support `ipv4-then-ipv6` and `ipv6-then-ipv4` modes
for `addr-family`. In the new `ipv4-then-ipv6` mode Trippy will first attempt to resolve the given hostname to an IPv4
address and, if no such address exists, it will attempt to resolve to an IPv6 address and only fail if neither are
available (and the opposite for the new `ipv6-then-ipv4` mode). The `addr-family` mode may also be set to be `ipv4`
or `ipv6` for IPv4 only and IPv6 only respectively.
To set the `addr-family` to be IPv6 with fallback to IPv4 you can set the `--addr-family` command line parameter:
```shell
trip example.com --addr-family ipv6-then-ipv4
```
To make the change permanent you can set the `addr-family` value in the `strategy` section of the configuration file:
```toml
[strategy]
addr-family = "ipv6-then-ipv4"
```
Note that Trippy supports both the `addr-family` entry in the configuration file and also the `--ipv4` (`-4`)
and `--ipv6` (`-6`) command line flags, all of which are optional. The command line flags (which are mutually exclusive)
take precedence over the config file entry and if neither are provided there it defaults to `ipv4-then-ipv6`.
### Extended Colors in TUI
Trippy allows the theme to be customized and supports the
named [ANSI colors](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors):
Black, Red, Green, Yellow, Blue, Magenta, Cyan, Gray, DarkGray, LightRed, LightGreen, LightYellow, LightBlue,
LightMagenta, LightCyan, White
The `0.10.0` release adds support for CSS [named colors](https://developer.mozilla.org/en-US/docs/Web/CSS/named-color) (
e.g. SkyBlue). Note that these are only supported on some platforms and terminals and may not render correctly
elsewhere.
See the [Theme Reference](https://github.com/fujiapple852/trippy#theme-reference)
### Simulation Testing
Manually testing all Trippy features in all modes and on all supported platforms is an increasingly time consuming and
error prone activity. Since the last release a significant effort has been made to increase the testing coverage,
including unit and integration testing.
In particular, the introduction of simulation testing allows for full end-to-end testing of all modes and features on
Linux, macOS and Windows without the need to mock or stub any behaviour _within_ Trippy.
This is achieved by creating a [TUN](https://en.wikipedia.org/wiki/TUN/TAP) device to simulate the behavior of network
nodes, responding to various pre-configured scenarios like packet loss and out-of-order arrivals.
Whilst not a change that directly benefits end users, this new testing approach should reduce the effort needed to test
each release of Trippy and help improve the overall reliability of the tool.
Note that the simulation testing is currently only supported for IPv4. See
the [Integration Testing](https://github.com/fujiapple852/trippy/issues/759) tracking issue for more details.
### Thanks
My thanks to all Trippy contributors, package maintainers and community members.
Feel free to drop by the Trippy Matrix room for a chat:
[](https://matrix.to/#/#trippy-dev:matrix.org)
Happy Tracing!
# 0.9.0
## Highlights
Trippy `0.9.0` introduces many new features, including tracing flows and ICMP extensions, the expansion of support for
the Paris tracing strategy to encompass IPv6/UDP, an unprivileged execution mode for macOS, a hop privacy mode and many
more. Additionally, this release includes several important bug fixes along with a range of new distribution packages.
### Tracing Flows
#### Flow ID
A tracing flow represents the sequence of hosts traversed from the source to the target. Trippy is now able to identify
individual flows within a trace and assign each a unique flow id. Trippy calculate a flow id for each round of tracing,
based on the sequence of hosts which responded during that round, taking care to account for rounds in which only a
subset of hosts responded. Tracing statistics, such as packet loss % and average RTT are recorded on a per-flow basis as
well as being aggregated across all flow.
Tracing flows adds to the existing capabilities provided by Trippy to assist
with [ECMP](https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing) (Equal-Cost Multi-Path Routing) when tracing
with UDP and TCP protocols. Some of these capabilities, such as
the [paris](https://github.com/libparistraceroute/libparistraceroute/wiki/Checksum)
and [dublin](https://github.com/insomniacslk/dublin-traceroute) tracing strategies, are designed to _restrict_ tracing
to a single flow, whilst others, such as the hop detail navigation mode (introduce in the last release) and tracing
flows, are designed to help _visualize_ tracing data in the presence of multiple flows. See
the `0.8.0` [release note](https://github.com/fujiapple852/trippy/releases/tag/0.8.0) for other such capabilities.
#### Tracing Flows in the TUI
The TUI has been enhanced with a new mode to help visualise flows. This can be toggled on and off with
the `toggle-flows` command (bound to the `f` key by default).
When toggled on, this mode display flow information as a chart in a new panel above the hops table. Flows can be
selected by using the left and right arrow keys (default key bindings). Flows are sorted by the number of rounds in
which a given flow id was observed, with the most frequent flow ids shown on the left. When entering this mode flow id 1
is selected automatically. The selected flow acts as a filter for the other parts of the TUI, including the hops table,
chart and maps views which only show data relevant to that specific flow.
<img width="60%" alt="flows" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/flows.png">
When toggled off, Trippy behaves as it did in previous versions where aggregated statistics (across all flows) are
shown. Note that per-flow data is always recorded, the toggle only influences how the data is displayed.
The number of flows visible in the TUI is limited and can be controlled by the `tui-max-flows` configuration items which
can be set via the command line or via the configuration file. By default up to 64 flows are shown.
The flows panel, as with all other parts of the TUI, can also be themed, see
the [theme reference](https://github.com/fujiapple852/trippy#theme-reference) for details.
#### Flow Reports
As well as visualising flows in the TUI, Trippy `0.9.0` introduces two new reports which make use of the tracing flow
data.
The new `flows` report mode records and print all flows observed during tracing.
The following command will run a TCP trace for 10 round and report all of the flows observed:
```shell
trip example.com --tcp -m flows -C 10
```
Sample output (truncated) showing three unique flows:
```text
flow 1: 192.168.1.1, 10.193.232.245, 218.102.40.38, 10.195.41.9, 172.217.27.14
flow 2: 192.168.1.1, 10.193.232.245, 218.102.40.22, 10.195.41.17, 172.217.27.14
flow 3: 192.168.1.1, 10.193.232.245, 218.102.40.38, 10.195.41.1, 172.217.27.14
```
Another new report, `dot`, outputs a [GraphViz](https://graphviz.org/) [`DOT`](https://graphviz.org/doc/info/lang.html)
format chart of all hosts observed during tracing.
The following command will run a TCP trace for 10 round and output a graph of flows in `DOT` format:
```shell
trip example.com --tcp -m dot -C 10
```
If you have a tool such as `dot` (Graphviz) installed you can use this to rendered the output in various formats, such
as PNG:
```shell
trip example.com --tcp -m dot -C 10 | dot -Tpng > path.png
```
Sample output:
<img width="60%" alt="dot" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/dot.png">
### ICMP Extensions
#### Parsing Extensions
Trippy `0.9.0` adds the ability to parse and display ICMP Multi-Part Messages (aka extensions). It supports both
compliant and non-compliant ICMP extensions as defined
in [section 5 of rfc4884](https://www.rfc-editor.org/rfc/rfc4884#section-5).
Trippy is able to parse and render any generic Extension Object but is also able to parse some well known Object
Classes, notably the MPLS class.
Support
for [additional classes](https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xml#icmp-parameters-ext-classes)
will be added to future versions of Trippy, see the ICMP
Extensions [tracking issue](https://github.com/fujiapple852/trippy/issues/33).
Parsing of ICMP extensions can be enabled by setting the `--icmp-extensions` (`-e`) command line flag or by adding
the `icmp-extensions` entry in the `strategy` section of the configuration file:
```toml
[strategy]
icmp-extensions = true
```
#### ICMP Extensions in the TUI
The TUI has been enhanced to display ICMP extensions in both the normal and hop detail navigation modes.
In normal mode, ICMP extensions are not shown by default but can be enabled by setting the `--tui-icmp-extension-mode`
command line flag or by adding the `tui-icmp-extension-mode` entry in the `tui` section of the configuration file:
```toml
[tui]
tui-icmp-extension-mode = "full"
```
This can be set to `off` (do not show ICMP extension data), `mpls` (shows a list of MPLS label(s) per hop), `full` (
shows all details of all extensions, such as `ttl`, `exp` and `bos` for MPLS) or `all` (the same as `full` but also
shows `class`, `subtype` and `bytes` for unknown extension objects).
The following screenshot shows ICMP extensions in normal mode with `tui-icmp-extension-mode` set to be `mpls`:
<img width="60%" alt="extensions" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/extensions.png">
In hop detail mode, the full details of all ICMP extension objects are always shown if parsing of ICMP extensions is
enabled.
The following screenshot shows ICMP extensions in hop detail mode:
<img width="60%" alt="extensions_detail" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/extensions_detail.png">
#### ICMP Extensions in Reports
ICMP extension information is also included the `json` and `stream` report modes.
Sample output for a single hop from the `json` report:
```json
{
"ttl": 14,
"hosts": [
{
"ip": "129.250.3.125",
"hostname": "ae-4.r25.sttlwa01.us.bb.gin.ntt.net"
}
],
"extensions": [
{
"mpls": {
"members": [
{
"label": 91106,
"exp": 0,
"bos": 1,
"ttl": 1
}
]
}
}
],
"loss_pct": "0.00",
"sent": 1,
"last": "178.16",
"recv": 1,
"avg": "178.16",
"best": "178.16",
"worst": "178.16",
"stddev": "0.00"
}
```
### Paris Tracing Strategy for IPv6/UDP
The work to support the remaining [paris](https://github.com/libparistraceroute/libparistraceroute/wiki/Checksum)
and [dublin](https://github.com/insomniacslk/dublin-traceroute) tracing modes continues in this release with the
addition of support for the Paris tracing strategy for IPv6/UDP.
As a reminder, unlike classic traceroute and MTR, these alternative tracing strategies do not encode the probe sequence
number in either the src or dest port of the UDP or TCP packet, but instead use other protocol and address family
specific techniques. Specifically, the Paris tracing strategy for IPv6/UDP utilizes the UDP checksum for this purposes
and manipulates the UDP payload to ensure packets remind valid.
By doing so, these strategies are able to keep the src and dest ports fixed which makes it much more likely (though not
guaranteed) that each round of tracing will follow the same path through the network (note that this is _not_ true for
the return path).
The following command runs a IPv6/UDP trace using the `paris` tracing strategy with fixed src and dest ports:
```shell
trip example.com --udp -6 -R paris -S 5000 -P 3500
```
Refer to the [tracking issue](https://github.com/fujiapple852/trippy/issues/274) for details of the work remaining to
support all ECMP strategies for both UDP and TCP for IPv4 and IPv6.
### Unprivileged Mode
Trippy normally requires elevated privileges due to the use of raw sockets. Enabling the required privileges for a given
platform can be achieved in several ways as in described
the [privileges](https://github.com/fujiapple852/trippy#privileges) section of the documentation.
This release of Trippy adds the ability to run _without_ elevated privileged on a subset of platforms, but with some
limitations which are described below.
The unprivileged mode can be enabled by adding the `--unprivileged` (`-u`) command line flag or by adding
the `unprivileged` entry in the `trippy` section of the configuration file:
```toml
[trippy]
unprivileged = true
```
The following command runs a trace in unprivileged mode:
```shell
trip example.com -u
```
Unprivileged mode is currently only supported on macOS. Linux support is possible and may be added in the future.
Unprivileged mode is not supported on NetBSD, OpenBSD, FreeBSD or Windows as these platforms do not support
the `IPPROTO_ICMP` socket type.
Unprivileged mode does not support the `paris` or `dublin` tracing strategies as these require raw sockets in order to
manipulate the UDP and IP header respectively.
See [#101](https://github.com/fujiapple852/trippy/issues/101) for further information.
### Resolve All DNS
Trippy can be provided with either an IP address or a hostname as the target for tracing. Trippy will resolve hostnames
to IP addresses via DNS lookup (using the configured DNS resolver, see the existing `--dns-resolve-method` flag) and
pick an arbitrary IP address from those returned.
Trippy also has the ability to trace to several targets simultaneously (for the ICMP protocol only) and can be provided
with a list of IP addresses and hostnames.
Trippy `0.9.0` combined these features and introduces a convenience flag `--dns-resolve-all` which resolves a given
hostname to all IP addresses and will begin to trace to all of them simultaneously.
<img width="60%" alt="dns_resolve_all" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/dns_resolve_all.png">
### Hop Privacy
At times it is desirable to share tracing information with others to help with diagnostics of a network problem. These
traces can contain sensitive information, such as IP addresses, hostnames and GeoIp details of the internet facing hops.
Users often wish to avoid exposing this data and are forced to redact the tracing output or screenshots.
Trippy `0.9.0` adds a new privacy feature, which hides all sensitive information for a configurable number of hops in
the hops table, chart and GeoIP world map.
The following screenshot shows the world map view with the sensitive information of some hops hidden:
<img width="60%" alt="privacy" src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.9.0/privacy.png">
The following command will hide all sensitive information for the first 3 hops (ttl 1, 2 & 3) in the TUI:
```shell
trip example.com --tui-privacy-max-ttl 3
```
This can also be made the default behaviour by setting the value in the Trippy configuration file:
```toml
[tui]
tui-privacy-max-ttl = 3
```
From within the TUI the privacy mode can be toggled on and off using the `toggle-privacy` TUI command (bound to the `p`
key by default).
Note the toggle is only available if `tui-privacy-max-ttl` is configured to be non-zero. Privacy mode is entered
automatically on startup to avoid any accidental exposure of sensitive data, such as when sharing a screen.
### Print Config Template
The `0.8.0` release of Trippy introduced
a [configuration file](https://github.com/fujiapple852/trippy#configuration-reference) and provided a sample
configuration file you could download. This release adds a command which generates a configuration template appropriate
for the specific version of Trippy.
The following command generates a `trippy.toml` configuration file with all possible configuration options specified and
set to their default values:
```shell
trip --print-config-template > trippy.toml
```
### Alternative Help Key Binding
Can't decide whether you want to use `h` or `?` to display help information? Well fear not, Trippy now supports
an `toggle-help-alt` TUI command (bound to the `?` key by default) in additional to the existing `toggle-help` TUI
command (bound to the `h` key by default).
### Improvements to Reports
This release fixes a bug that prevented reverse DNS lookup from working in all reporting modes.
The list of IPs associated with a given hop have also been added to the `csv` and all tabular reports. ICMP extension
data has also been included in several reports.
Note that these are breaking change as the output of the reports has changed.
### New Binary Asset Downloads
The list of operating systems, CPU architectures and environments which have pre-build binary assets available for
download has been greatly expanded for the `0.9.0` release.
This includes assets for Linux, macOS, Windows, NetBSD and FreeBSD. Assets are available for `x86_64`, `aarch64`
and `arm7` and includes builds for various environments such as `gnu` and `musl` where appropriate. There are also
pre-build `RPM` and `deb` downloads available. See
the [Binary Asset Download](https://github.com/fujiapple852/trippy#binary-asset-download) section for a full list.
Note that Trippy `0.9.0` has only been [tested](https://github.com/fujiapple852/trippy/issues/836) on a small subset of
these platforms.
### New Distribution Packages
Since the last release Trippy has been added as an official WinGet package (kudos to @mdanish-kh and
@BrandonWanHuanSheng!) and can be installed as follows:
```shell
winget install trippy
```
Trippy has also been added to the scoop `Main` bucket (thanks to @StarsbySea!) and can be installed as follows:
```shell
scoop install trippy
```
You can find the full list of [distributions](https://github.com/fujiapple852/trippy/tree/master#distributions) in the
documentation.
### Thanks
My thanks to all Trippy contributors, package maintainers and community members.
Feel free to drop by the Trippy Matrix room for a chat:
[](https://matrix.to/#/#trippy-dev:matrix.org)
Happy Tracing!
## New Contributors
- @c-git made their first contribution in https://github.com/fujiapple852/trippy/pull/632
- @trkelly23 made their first contribution in https://github.com/fujiapple852/trippy/pull/788
# 0.8.0
## Highlights
The `0.8.0` release of Trippy brings several new features, UX enhancements, and quality of life improvements, as well as
various small fixes and other minor improvements.
#### Hop Detail Navigation
Trippy offers various mechanisms to visualize [ECMP](https://en.wikipedia.org/wiki/Equal-cost_multi-path_routing) (
Equal-Cost Multi-Path Routing) when tracing with UDP and TCP protocols. Features include displaying all hosts for a
given hop in a scrollable table, limiting the number of hosts shown per hop (showing the % of traffic for each host),
and greying out hops that are not part of a specific tracing round.
Despite these helpful features, visualizing a complete trace can be challenging when there are numerous hosts for some
hops, which is common in environments where ECMP is heavily utilized.
This release enhances ECMP visualization support by introducing a hop detail navigation mode, which can be toggled on
and off by pressing `d` (default key binding). This mode displays multiline information for the selected hop only,
including IP, hostname, AS, and GeoIP details about a single host for the hop. Users can navigate forward and backward
between hosts in a given hop by pressing `,` and `.` (default key bindings), respectively.
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.8.0/hop_details.png" width="60%">
In addition to visualizing ECMP, Trippy also supports alternative tracing strategies to assist with ECMP routing, which
are described below.
#### Paris Tracing Strategy
Trippy already supports both classic and [dublin](https://github.com/insomniacslk/dublin-traceroute) tracing strategies,
and this release adds support for the [paris](https://github.com/libparistraceroute/libparistraceroute/wiki/Checksum)
tracing strategy for the UDP protocol.
Unlike classic traceroute and MTR, these alternative tracing strategies do not encode the probe sequence number in
either the src or dest port of the UDP or TCP packet, but instead use other protocol and address family specific
techniques.
This means that every probe in a trace can share common values for the src & dest hosts and ports which, when combined
with the protocol, is typically what is used to making traffic route decisions in ECMP routing. This means that these
alternative tracing strategies significantly increase the likelihood that the same path is followed for each probe in a
trace (but not the return path!) in the presence of ECMP routing.
The following command runs a UDP trace using the new `paris` tracing strategy with fixed src and dest ports (the src and
dest hosts and the protocol are always fixed) and will therefore likely follow a common path for each probe in the
trace:
```shell
trip www.example.com --udp -R paris -S 5000 -P 3500
```
Future Trippy versions will build upon these strategies and further improve the ability to control and visualize ECMP
routing, refer to the [tracking issue](https://github.com/fujiapple852/trippy/issues/274) for further details.
#### GeoIp Information & Interactive Map
Trippy now supports the ability to look up and display GeoIP information from a user-provided
MaxMind [GeoLite2 City database](https://dev.maxmind.com/geoip/geolite2-free-geolocation-data). This information is
displayed per host in the hop table (for both normal and new detail navigation modes) and can be shown in various
formats. For example, short form like "San Jose, CA, US" or long form like "San Jose, California, United States, North
America," or latitude, longitude, and accuracy radius like "37.3512, -121.8846 (~20km)".
The following command enables GeoIP lookup from the provided `GeoLite2-City.mmdb` file and will show long form locations
in the hop table:
```shell
trip example.com --geoip-mmdb-file GeoLite2-City.mmdb --tui-geoip-mode long
```
Additionally, Trippy features a new interactive map screen that can be toggled on and off by pressing `m` (default key
binding). This screen displays a world map and plots the location of all hosts for all hops in the current trace, as
well as highlighting the location of the selected hop.
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.8.0/world_map.png" width="60%">
#### Autonomous System Display Enhancements
Trippy has long offered the ability to look up and display AS information. This release makes this feature more flexible
by allowing different AS details to be shown in the hops table, including AS number, AS name, prefix CIDR, and registry
details.
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.8.0/as_info.png" width="60%">
The following command enables AS lookup and will display the prefix CIDR for each host in the TUI:
```shell
trip example.com -z true -r resolv --tui-as-mode prefix
```
This release also fixes a limitation in earlier versions of Trippy that prevented the lookup of AS information for IP
addresses without a corresponding `PTR` DNS record.
#### UI Cleanup & Configuration Dialog
The number of configurable parameters in Trippy has grown significantly, surpassing the number that can be comfortably
displayed in the TUI header section. Previous Trippy versions displayed an arbitrarily chosen subset of these
parameters, many of which have limited value for users and consume valuable screen space.
This release introduces a new interactive settings dialog that can be toggled on and off with `s` (default key binding)
to display all configured parameters. The TUI header has also been cleaned up to show only the most relevant
information, specifically the protocol and address family, the AS info toggle, the hop details toggle, and the max-hosts
setting.
<img src="https://raw.githubusercontent.com/fujiapple852/trippy/master/assets/0.8.0/settings.png" width="60%">
#### Configuration File
The previous Trippy release introduced the ability to customize the TUI color theme and key bindings, both of which
could be specified by command-line arguments. While functional, this method is inconvenient when configuring a large
number of colors or keys.
This release adds support for a Trippy configuration file, allowing for persistent storage of color themes, key
bindings, and all other configuration items supported by Trippy.
For a sample configuration file showing all possible configurable items that are available, see
the [configuration reference](https://github.com/fujiapple852/trippy#configuration-reference) for details.
#### Shell Completions
This release enables the generation of shell completions for various shells, including bash, zsh, PowerShell, and fish,
using the new `--generate` command-line flag.
The following command will generate and store shell completions for the fish shell:
```shell
trip --generate fish > ~/.config/fish/completions/trip.fish
```
#### Improved Error Reporting & Debug Logging
This release adds a number of command-line flags to enable debug logging, enhancing the ability to diagnose failures.
For example, the following command can be used to run tracing with no output, except for debug output in a format
suitable to be displayed with `chrome://tracing` or similar tools:
```shell
trip www.example.com -m silent -v --log-format chrome
```
Socket errors have also been augmented with contextual information, such as the socket address for a bind failure, to
help with the diagnosis of issues.
#### New Distribution Packages
Trippy is now also available as a Nix package (@figsoda), a FreeBSD port (@ehaupt) and a Windows Scoop package. This
release also re-enables support for a `musl` binary which was disabled in `0.7.0` due to a bug in a critical library
used by Trippy.
See [distributions](https://github.com/fujiapple852/trippy#distributions) for the full list of available packages.
My thanks, as ever, to all Trippy contributors!
## New Contributors
- @utkarshgupta137 made their first contribution in https://github.com/fujiapple852/trippy/pull/537
# 0.7.0
## Highlights
The major highlight of the 0.7.0 release of Trippy is the addition of full support for Windows, for all tracing modes
and protocols! 🎉. This has been many months in the making and is thanks to the hard work and perseverance of @zarkdav.
This release also sees the introduction of custom Tui themes and key bindings, `deb` and `rpm` package releases, as well
as several important bug fixes.
My thanks to all the contributors!
# 0.6.0
## Highlights
The first official release of Trippy!
================================================
FILE: crates/README.md
================================================
## Crates
The following is a list of the crates defined by Trippy and their purposes:
### `trippy`
A binary crate for the Trippy application and a library crate. This is the crate you would use if you wish to install
and run Trippy as a standalone tool.
```shell
cargo install --locked trippy
```
It can also be used as library for crates that wish to use the Trippy tracing functionality.
> [!NOTE]
> The `trippy` crate has `tui` as a default feature and so you should disable default features when using it as a
> library.
```shell
cargo add trippy --no-default-features --features core,dns
```
### `trippy-core`
A library crate providing the core Trippy tracing functionality. This crate is used by the Trippy application and is
the crate you would use if you wish to provide the Trippy tracing functionality in your own application.
```shell
cargo add trippy-core
```
### `trippy-packet`
A library crate which provides packet wire formats and packet parsing functionality. This crate is used by the Trippy
application and is the crate you would use if you wish to provide packet parsing functionality in your own application.
```shell
cargo add trippy-packet
```
### `trippy-dns`
A library crate for performing forward and reverse lazy DNS resolution. This crate is designed to be used by the Trippy
application but may also be useful for other applications that need to perform forward and reverse lazy DNS resolution.
```shell
cargo add trippy-dns
```
### `trippy-privilege`
A library crate for discovering platform privileges. This crate is designed to be used by the Trippy application but
may also be useful for other applications.
```shell
cargo add trippy-privilege
```
### `trippy-tui`
A library crate for the Trippy terminal user interface.
```shell
cargo add trippy-tui
```
================================================
FILE: crates/trippy/Cargo.toml
================================================
[package]
name = "trippy"
description = "A network diagnostic tool"
version.workspace = true
authors.workspace = true
documentation.workspace = true
homepage.workspace = true
repository.workspace = true
readme = "README.md"
license.workspace = true
edition.workspace = true
rust-version.workspace = true
keywords.workspace = true
categories.workspace = true
[[bin]]
name = "trip"
path = "src/main.rs"
required-features = ["tui"]
[features]
default = ["tui"]
tui = ["trippy-tui", "anyhow"]
core = ["trippy-core"]
privilege = ["trippy-privilege"]
dns = ["trippy-dns"]
packet = ["trippy-packet"]
[dependencies]
trippy-tui = { workspace = true, optional = true }
trippy-core = { workspace = true, optional = true }
trippy-privilege = { workspace = true, optional = true }
trippy-dns = { workspace = true, optional = true }
trippy-packet = { workspace = true, optional = true }
anyhow = { workspace = true, optional = true }
[lints]
workspace = true
[package.metadata.generate-rpm]
assets = [
{ source = "target/release/trip", dest = "/usr/bin/trip", mode = "755" },
]
================================================
FILE: crates/trippy/src/lib.rs
================================================
#![allow(
rustdoc::broken_intra_doc_links,
rustdoc::bare_urls,
clippy::doc_markdown,
clippy::doc_lazy_continuation
)]
#![doc = include_str!("../README.md")]
// Re-export the user facing libraries, so they may be used from trippy crate directly.
#[cfg(feature = "core")]
/// A network tracer.
pub mod core {
pub use trippy_core::*;
}
#[cfg(feature = "dns")]
/// A lazy DNS resolver.
pub mod dns {
pub use trippy_dns::*;
}
#[cfg(feature = "privilege")]
/// Discover platform privileges.
pub mod privilege {
pub use trippy_privilege::*;
}
#[cfg(feature = "packet")]
/// Network packets.
pub mod packet {
pub use trippy_packet::*;
}
================================================
FILE: crates/trippy/src/main.rs
================================================
fn main() -> anyhow::Result<()> {
trippy_tui::trippy()
}
================================================
FILE: crates/trippy-core/Cargo.toml
================================================
[package]
name = "trippy-core"
description = "A network tracing library"
version.workspace = true
authors.workspace = true
homepage.workspace = true
repository.workspace = true
readme.workspace = true
license.workspace = true
edition.workspace = true
rust-version.workspace = true
keywords.workspace = true
categories.workspace = true
[dependencies]
trippy-packet.workspace = true
trippy-privilege.workspace = true
arrayvec.workspace = true
bitflags.workspace = true
derive_more = { workspace = true, default-features = false, features = ["mul", "add", "add_assign"] }
indexmap = { workspace = true, default-features = false, features = ["std"] }
itertools.workspace = true
parking_lot.workspace = true
socket2 = { workspace = true, features = ["all"] }
thiserror.workspace = true
tracing.workspace = true
[target.'cfg(unix)'.dependencies]
nix = { workspace = true, default-features = false, features = ["user", "poll", "net"] }
[target.'cfg(windows)'.dependencies]
paste.workspace = true
widestring.workspace = true
windows-sys = { workspace = true, features = ["Win32_Foundation", "Win32_Networking_WinSock", "Win32_System_IO", "Win32_NetworkManagement_IpHelper", "Win32_NetworkManagement_Ndis", "Win32_System_IO", "Win32_System_Threading", "Win32_Security"] }
[dev-dependencies]
anyhow.workspace = true
futures-concurrency.workspace = true
hex-literal.workspace = true
mockall.workspace = true
rand.workspace = true
serde = { workspace = true, default-features = false, features = ["derive", "std"] }
test-case.workspace = true
tokio-util.workspace = true
tokio = { workspace = true, features = ["full"] }
toml = { workspace = true, default-features = false, features = ["parse"] }
tracing-subscriber = { workspace = true, default-features = false, features = ["env-filter", "fmt"] }
[target.'cfg(any(target_os = "macos", target_os = "linux", target_os = "windows"))'.dev-dependencies]
tun-rs = { workspace = true, features = ["async"] }
[features]
# Enable simulation integration tests
sim-tests = []
[lints]
workspace = true
================================================
FILE: crates/trippy-core/src/builder.rs
================================================
use crate::config::{ChannelConfig, StateConfig, StrategyConfig};
use crate::constants::MAX_INITIAL_SEQUENCE;
use crate::error::Result;
use crate::{
Error, IcmpExtensionParseMode, MAX_TTL, MaxInflight, MaxRounds, MultipathStrategy, PacketSize,
PayloadPattern, PortDirection, PrivilegeMode, Protocol, Sequence, TimeToLive, TraceId, Tracer,
TypeOfService,
};
use std::net::IpAddr;
use std::num::NonZeroUsize;
use std::time::Duration;
/// Build a tracer.
///
/// This is a convenience builder to simplify the creation of execution of a
/// tracer.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use trippy_core::{Builder, MultipathStrategy, Port, PortDirection, PrivilegeMode, Protocol};
///
/// let addr = std::net::IpAddr::from([1, 2, 3, 4]);
/// let tracer = Builder::new(addr)
/// .privilege_mode(PrivilegeMode::Unprivileged)
/// .protocol(Protocol::Udp)
/// .multipath_strategy(MultipathStrategy::Dublin)
/// .port_direction(PortDirection::FixedBoth(Port(33434), Port(3500)))
/// .build()?;
/// # Ok(())
/// # }
/// ```
///
/// # See Also
///
/// - [`Tracer`] - A traceroute implementation.
#[derive(Debug)]
pub struct Builder {
interface: Option<String>,
source_addr: Option<IpAddr>,
target_addr: IpAddr,
privilege_mode: PrivilegeMode,
protocol: Protocol,
packet_size: PacketSize,
payload_pattern: PayloadPattern,
tos: TypeOfService,
icmp_extension_parse_mode: IcmpExtensionParseMode,
read_timeout: Duration,
tcp_connect_timeout: Duration,
trace_identifier: TraceId,
max_rounds: Option<MaxRounds>,
first_ttl: TimeToLive,
max_ttl: TimeToLive,
grace_duration: Duration,
max_inflight: MaxInflight,
initial_sequence: Sequence,
multipath_strategy: MultipathStrategy,
port_direction: PortDirection,
min_round_duration: Duration,
max_round_duration: Duration,
max_samples: usize,
max_flows: usize,
drop_privileges: bool,
}
impl Default for Builder {
fn default() -> Self {
Self {
interface: None,
source_addr: None,
target_addr: ChannelConfig::default().target_addr,
privilege_mode: ChannelConfig::default().privilege_mode,
protocol: ChannelConfig::default().protocol,
packet_size: ChannelConfig::default().packet_size,
payload_pattern: ChannelConfig::default().payload_pattern,
tos: ChannelConfig::default().tos,
icmp_extension_parse_mode: ChannelConfig::default().icmp_extension_parse_mode,
read_timeout: ChannelConfig::default().read_timeout,
tcp_connect_timeout: ChannelConfig::default().tcp_connect_timeout,
trace_identifier: StrategyConfig::default().trace_identifier,
max_rounds: StrategyConfig::default().max_rounds,
first_ttl: StrategyConfig::default().first_ttl,
max_ttl: StrategyConfig::default().max_ttl,
grace_duration: StrategyConfig::default().grace_duration,
max_inflight: StrategyConfig::default().max_inflight,
initial_sequence: StrategyConfig::default().initial_sequence,
multipath_strategy: StrategyConfig::default().multipath_strategy,
port_direction: StrategyConfig::default().port_direction,
min_round_duration: StrategyConfig::default().min_round_duration,
max_round_duration: StrategyConfig::default().max_round_duration,
max_samples: StateConfig::default().max_samples,
max_flows: StateConfig::default().max_flows,
drop_privileges: false,
}
}
}
impl Builder {
/// Build a tracer builder for a given target.
///
/// # Examples
///
/// Basic usage:
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use trippy_core::Builder;
///
/// let addr = std::net::IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn new(target_addr: IpAddr) -> Self {
Self {
target_addr,
..Default::default()
}
}
/// Set the source address.
///
/// If not set then the source address will be discovered based on the
/// target address and the interface.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let source_addr = IpAddr::from([192, 168, 1, 1]);
/// let tracer = Builder::new(addr).source_addr(Some(source_addr)).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn source_addr(self, source_addr: Option<IpAddr>) -> Self {
Self {
source_addr,
..self
}
}
/// Set the source interface.
///
/// If the source interface is provided it will be used to look up the IPv4
/// or IPv6 source address.
///
/// If not provided the source address will be determined by OS based on
/// the target IPv4 or IPv6 address.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).interface(Some("eth0")).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn interface<S: Into<String>>(self, interface: Option<S>) -> Self {
Self {
interface: interface.map(Into::into),
..self
}
}
/// Set the protocol.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::{Builder, Protocol};
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).protocol(Protocol::Udp).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn protocol(self, protocol: Protocol) -> Self {
Self { protocol, ..self }
}
/// Set the trace identifier.
///
/// If not set then 0 will be used as the trace identifier.
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).trace_identifier(12345).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn trace_identifier(self, trace_id: u16) -> Self {
Self {
trace_identifier: TraceId(trace_id),
..self
}
}
/// Set the privilege mode.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::{Builder, PrivilegeMode};
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .privilege_mode(PrivilegeMode::Unprivileged)
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn privilege_mode(self, privilege_mode: PrivilegeMode) -> Self {
Self {
privilege_mode,
..self
}
}
/// Set the multipath strategy.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::{Builder, MultipathStrategy};
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .multipath_strategy(MultipathStrategy::Paris)
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn multipath_strategy(self, multipath_strategy: MultipathStrategy) -> Self {
Self {
multipath_strategy,
..self
}
}
/// Set the packet size.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).packet_size(128).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn packet_size(self, packet_size: u16) -> Self {
Self {
packet_size: PacketSize(packet_size),
..self
}
}
/// Set the payload pattern.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).payload_pattern(0xff).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn payload_pattern(self, payload_pattern: u8) -> Self {
Self {
payload_pattern: PayloadPattern(payload_pattern),
..self
}
}
/// Set the type of service.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).tos(0x1a).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn tos(self, tos: u8) -> Self {
Self {
tos: TypeOfService(tos),
..self
}
}
/// Set the ICMP extensions mode.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::{Builder, IcmpExtensionParseMode};
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .icmp_extension_parse_mode(IcmpExtensionParseMode::Enabled)
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn icmp_extension_parse_mode(
self,
icmp_extension_parse_mode: IcmpExtensionParseMode,
) -> Self {
Self {
icmp_extension_parse_mode,
..self
}
}
/// Set the read timeout.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use std::time::Duration;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .read_timeout(Duration::from_millis(50))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn read_timeout(self, read_timeout: Duration) -> Self {
Self {
read_timeout,
..self
}
}
/// Set the TCP connect timeout.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use std::time::Duration;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .tcp_connect_timeout(Duration::from_millis(100))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn tcp_connect_timeout(self, tcp_connect_timeout: Duration) -> Self {
Self {
tcp_connect_timeout,
..self
}
}
/// Set the maximum number of rounds.
///
/// If set to `None` then the tracer will run indefinitely, otherwise it
/// will stop after the given number of rounds.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).max_rounds(Some(10)).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_rounds(self, max_rounds: Option<usize>) -> Self {
Self {
max_rounds: max_rounds
.and_then(|max_rounds| NonZeroUsize::new(max_rounds).map(MaxRounds)),
..self
}
}
/// Set the first ttl.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).first_ttl(2).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn first_ttl(self, first_ttl: u8) -> Self {
Self {
first_ttl: TimeToLive(first_ttl),
..self
}
}
/// Set the maximum ttl.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).max_ttl(16).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_ttl(self, max_ttl: u8) -> Self {
Self {
max_ttl: TimeToLive(max_ttl),
..self
}
}
/// Set the grace duration.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use std::time::Duration;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .grace_duration(Duration::from_millis(100))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn grace_duration(self, grace_duration: Duration) -> Self {
Self {
grace_duration,
..self
}
}
/// Set the max number of probes in flight at any given time.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).max_inflight(22).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_inflight(self, max_inflight: u8) -> Self {
Self {
max_inflight: MaxInflight(max_inflight),
..self
}
}
/// Set the initial sequence number.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).initial_sequence(35000).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn initial_sequence(self, initial_sequence: u16) -> Self {
Self {
initial_sequence: Sequence(initial_sequence),
..self
}
}
/// Set the port direction.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::{Builder, Port, PortDirection};
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .port_direction(PortDirection::FixedDest(Port(8080)))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn port_direction(self, port_direction: PortDirection) -> Self {
Self {
port_direction,
..self
}
}
/// Set the minimum round duration.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use std::time::Duration;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .min_round_duration(Duration::from_millis(500))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn min_round_duration(self, min_round_duration: Duration) -> Self {
Self {
min_round_duration,
..self
}
}
/// Set the maximum round duration.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use std::time::Duration;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr)
/// .max_round_duration(Duration::from_millis(1500))
/// .build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_round_duration(self, max_round_duration: Duration) -> Self {
Self {
max_round_duration,
..self
}
}
/// Set the maximum number of samples to record.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).max_samples(256).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_samples(self, max_samples: usize) -> Self {
Self {
max_samples,
..self
}
}
/// Set the maximum number of flows to record.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).max_flows(64).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn max_flows(self, max_flows: usize) -> Self {
Self { max_flows, ..self }
}
/// Drop privileges after connection is established.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).drop_privileges(true).build()?;
/// # Ok(())
/// # }
/// ```
#[must_use]
pub fn drop_privileges(self, drop_privileges: bool) -> Self {
Self {
drop_privileges,
..self
}
}
/// Build the `Tracer`.
///
/// # Examples
///
/// ```no_run
/// # fn main() -> anyhow::Result<()> {
/// use std::net::IpAddr;
/// use trippy_core::Builder;
///
/// let addr = IpAddr::from([1, 1, 1, 1]);
/// let tracer = Builder::new(addr).build()?;
/// # Ok(())
/// # }
/// ```
///
/// # Errors
///
/// This function will return `Error::BadConfig` if the configuration is invalid.
pub fn build(self) -> Result<Tracer> {
match (self.protocol, self.port_direction) {
(Protocol::Udp, P
gitextract_swvmlbvf/
├── .config/
│ ├── spellcheck.toml
│ └── trippy.dic
├── .devcontainer/
│ └── devcontainer.json
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ └── feature_request.md
│ ├── dependabot.yml
│ └── workflows/
│ ├── ci.yml
│ ├── deploy.yml
│ └── release.yml
├── .gitignore
├── AGENTS.md
├── CHANGELOG.md
├── CONTRIBUTING.md
├── Cargo.toml
├── Dockerfile
├── LICENSE
├── README.md
├── RELEASES.md
├── crates/
│ ├── README.md
│ ├── trippy/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── lib.rs
│ │ └── main.rs
│ ├── trippy-core/
│ │ ├── Cargo.toml
│ │ ├── src/
│ │ │ ├── builder.rs
│ │ │ ├── config.rs
│ │ │ ├── constants.rs
│ │ │ ├── error.rs
│ │ │ ├── flows.rs
│ │ │ ├── lib.rs
│ │ │ ├── net/
│ │ │ │ ├── channel.rs
│ │ │ │ ├── common.rs
│ │ │ │ ├── extension.rs
│ │ │ │ ├── ipv4.rs
│ │ │ │ ├── ipv6.rs
│ │ │ │ ├── platform/
│ │ │ │ │ ├── byte_order.rs
│ │ │ │ │ ├── unix.rs
│ │ │ │ │ └── windows.rs
│ │ │ │ ├── platform.rs
│ │ │ │ ├── socket.rs
│ │ │ │ └── source.rs
│ │ │ ├── net.rs
│ │ │ ├── probe.rs
│ │ │ ├── state.rs
│ │ │ ├── strategy.rs
│ │ │ ├── tracer.rs
│ │ │ └── types.rs
│ │ └── tests/
│ │ ├── resources/
│ │ │ ├── simulation/
│ │ │ │ ├── ipv4_icmp.toml
│ │ │ │ ├── ipv4_icmp_gaps.toml
│ │ │ │ ├── ipv4_icmp_min.toml
│ │ │ │ ├── ipv4_icmp_ooo.toml
│ │ │ │ ├── ipv4_icmp_pattern.toml
│ │ │ │ ├── ipv4_icmp_quick.toml
│ │ │ │ ├── ipv4_icmp_tos.toml
│ │ │ │ ├── ipv4_icmp_wrap.toml
│ │ │ │ ├── ipv4_tcp_fixed_dest.toml
│ │ │ │ ├── ipv4_udp_classic_fixed_dest.toml
│ │ │ │ ├── ipv4_udp_classic_fixed_src.toml
│ │ │ │ ├── ipv4_udp_classic_privileged_tos.toml
│ │ │ │ ├── ipv4_udp_classic_unprivileged.toml
│ │ │ │ ├── ipv4_udp_classic_unprivileged_tos.toml
│ │ │ │ ├── ipv4_udp_dublin_fixed_both.toml
│ │ │ │ ├── ipv4_udp_paris_fixed_both.toml
│ │ │ │ ├── ipv6_icmp.toml
│ │ │ │ ├── ipv6_icmp_min.toml
│ │ │ │ ├── ipv6_icmp_pattern.toml
│ │ │ │ ├── ipv6_tcp_fixed_dest.toml
│ │ │ │ ├── ipv6_udp_classic_fixed_dest.toml
│ │ │ │ ├── ipv6_udp_classic_fixed_src.toml
│ │ │ │ ├── ipv6_udp_classic_unprivileged.toml
│ │ │ │ ├── ipv6_udp_classic_unprivileged_tos.toml
│ │ │ │ ├── ipv6_udp_dublin_fixed_both.toml
│ │ │ │ └── ipv6_udp_paris_fixed_both.toml
│ │ │ └── state/
│ │ │ ├── all_status.toml
│ │ │ ├── floss_bloss.toml
│ │ │ ├── full_completed.toml
│ │ │ ├── full_mixed.toml
│ │ │ ├── minimal.toml
│ │ │ ├── nat.toml
│ │ │ ├── no_latency.toml
│ │ │ ├── non_default_minimum_ttl.toml
│ │ │ └── tos.toml
│ │ └── sim/
│ │ ├── main.rs
│ │ ├── network/
│ │ │ ├── ipv4.rs
│ │ │ └── ipv6.rs
│ │ ├── network.rs
│ │ ├── simulation.rs
│ │ ├── tests.rs
│ │ ├── tracer.rs
│ │ └── tun_device.rs
│ ├── trippy-dns/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── config.rs
│ │ ├── lazy_resolver.rs
│ │ ├── lib.rs
│ │ └── resolver.rs
│ ├── trippy-packet/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ ├── buffer.rs
│ │ ├── checksum.rs
│ │ ├── error.rs
│ │ ├── icmp_extension.rs
│ │ ├── icmpv4.rs
│ │ ├── icmpv6.rs
│ │ ├── ip.rs
│ │ ├── ipv4.rs
│ │ ├── ipv6.rs
│ │ ├── lib.rs
│ │ ├── tcp.rs
│ │ └── udp.rs
│ ├── trippy-privilege/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── lib.rs
│ └── trippy-tui/
│ ├── Cargo.toml
│ ├── build.rs
│ ├── locales.toml
│ ├── src/
│ │ ├── app.rs
│ │ ├── config/
│ │ │ ├── binding.rs
│ │ │ ├── cmd.rs
│ │ │ ├── columns.rs
│ │ │ ├── constants.rs
│ │ │ ├── file.rs
│ │ │ └── theme.rs
│ │ ├── config.rs
│ │ ├── frontend/
│ │ │ ├── binding.rs
│ │ │ ├── columns.rs
│ │ │ ├── config.rs
│ │ │ ├── render/
│ │ │ │ ├── app.rs
│ │ │ │ ├── bar.rs
│ │ │ │ ├── body.rs
│ │ │ │ ├── bsod.rs
│ │ │ │ ├── chart.rs
│ │ │ │ ├── flows.rs
│ │ │ │ ├── footer.rs
│ │ │ │ ├── header.rs
│ │ │ │ ├── help.rs
│ │ │ │ ├── histogram.rs
│ │ │ │ ├── history.rs
│ │ │ │ ├── settings.rs
│ │ │ │ ├── splash.rs
│ │ │ │ ├── table.rs
│ │ │ │ ├── tabs.rs
│ │ │ │ ├── util.rs
│ │ │ │ └── world.rs
│ │ │ ├── render.rs
│ │ │ ├── theme.rs
│ │ │ └── tui_app.rs
│ │ ├── frontend.rs
│ │ ├── geoip.rs
│ │ ├── lib.rs
│ │ ├── locale.rs
│ │ ├── print.rs
│ │ ├── report/
│ │ │ ├── csv.rs
│ │ │ ├── dot.rs
│ │ │ ├── flows.rs
│ │ │ ├── json.rs
│ │ │ ├── silent.rs
│ │ │ ├── stream.rs
│ │ │ ├── table.rs
│ │ │ └── types.rs
│ │ ├── report.rs
│ │ └── util.rs
│ └── tests/
│ └── resources/
│ └── snapshots/
│ ├── trippy_tui__config__tests__compare_snapshot@trip.snap
│ ├── trippy_tui__config__tests__compare_snapshot@trip_--help.snap
│ ├── trippy_tui__config__tests__compare_snapshot@trip_-h.snap
│ ├── trippy_tui__print__tests__output@generate_bash_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_elvish_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_fish_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_man_page.snap
│ ├── trippy_tui__print__tests__output@generate_powershell_shell_completions.snap
│ ├── trippy_tui__print__tests__output@generate_zsh_shell_completions.snap
│ ├── trippy_tui__print__tests__output@tui_binding_commands_match.snap
│ └── trippy_tui__print__tests__output@tui_theme_items_match.snap
├── deny.toml
├── docs/
│ ├── .gitignore
│ ├── README.md
│ ├── astro.config.mjs
│ ├── package.json
│ ├── public/
│ │ └── CNAME
│ ├── src/
│ │ ├── content/
│ │ │ ├── config.ts
│ │ │ ├── docs/
│ │ │ │ ├── 0.12.2/
│ │ │ │ │ ├── development/
│ │ │ │ │ │ └── crates.md
│ │ │ │ │ ├── guides/
│ │ │ │ │ │ ├── faq.md
│ │ │ │ │ │ ├── privileges.md
│ │ │ │ │ │ ├── recommendation.md
│ │ │ │ │ │ ├── usage.md
│ │ │ │ │ │ └── windows_firewall.md
│ │ │ │ │ ├── index.mdx
│ │ │ │ │ ├── reference/
│ │ │ │ │ │ ├── bindings.md
│ │ │ │ │ │ ├── cli.md
│ │ │ │ │ │ ├── column.md
│ │ │ │ │ │ ├── configuration.md
│ │ │ │ │ │ ├── locale.md
│ │ │ │ │ │ ├── theme.md
│ │ │ │ │ │ └── version.md
│ │ │ │ │ └── start/
│ │ │ │ │ ├── features.md
│ │ │ │ │ ├── getting-started.mdx
│ │ │ │ │ └── installation.md
│ │ │ │ ├── 0.13.0/
│ │ │ │ │ ├── development/
│ │ │ │ │ │ └── crates.md
│ │ │ │ │ ├── guides/
│ │ │ │ │ │ ├── faq.md
│ │ │ │ │ │ ├── privileges.md
│ │ │ │ │ │ ├── recommendation.md
│ │ │ │ │ │ ├── usage.md
│ │ │ │ │ │ └── windows_firewall.md
│ │ │ │ │ ├── index.mdx
│ │ │ │ │ ├── reference/
│ │ │ │ │ │ ├── bindings.md
│ │ │ │ │ │ ├── cli.md
│ │ │ │ │ │ ├── column.md
│ │ │ │ │ │ ├── configuration.md
│ │ │ │ │ │ ├── locale.md
│ │ │ │ │ │ ├── overview.mdx
│ │ │ │ │ │ ├── theme.md
│ │ │ │ │ │ └── version.md
│ │ │ │ │ └── start/
│ │ │ │ │ ├── features.md
│ │ │ │ │ ├── getting-started.mdx
│ │ │ │ │ └── installation.md
│ │ │ │ ├── development/
│ │ │ │ │ └── crates.md
│ │ │ │ ├── guides/
│ │ │ │ │ ├── docker.md
│ │ │ │ │ ├── faq.md
│ │ │ │ │ ├── privileges.md
│ │ │ │ │ ├── recommendation.md
│ │ │ │ │ ├── usage.md
│ │ │ │ │ └── windows_firewall.md
│ │ │ │ ├── index.mdx
│ │ │ │ ├── reference/
│ │ │ │ │ ├── bindings.md
│ │ │ │ │ ├── cli.md
│ │ │ │ │ ├── column.md
│ │ │ │ │ ├── configuration.md
│ │ │ │ │ ├── locale.md
│ │ │ │ │ ├── overview.mdx
│ │ │ │ │ ├── theme.md
│ │ │ │ │ └── version.md
│ │ │ │ └── start/
│ │ │ │ ├── features.md
│ │ │ │ ├── getting-started.mdx
│ │ │ │ └── installation.md
│ │ │ └── versions/
│ │ │ ├── 0.12.2.json
│ │ │ └── 0.13.0.json
│ │ ├── env.d.ts
│ │ └── styles/
│ │ └── custom.css
│ └── tsconfig.json
├── dprint.json
├── examples/
│ ├── README.md
│ ├── hello-world/
│ │ ├── Cargo.toml
│ │ └── src/
│ │ └── main.rs
│ └── toy-traceroute/
│ ├── Cargo.toml
│ └── src/
│ └── main.rs
├── snap/
│ └── snapcraft.yaml
├── trippy-config-sample.toml
└── ubuntu-ppa/
├── Dockerfile
├── README.debian
├── README.md
├── cargo.config
├── changelog
├── control
├── copyright
├── release.sh
├── rules
├── source/
│ ├── format
│ └── include-binaries
├── trippy.docs
└── trippy.install
SYMBOL INDEX (2068 symbols across 94 files)
FILE: crates/trippy-core/src/builder.rs
type Builder (line 39) | pub struct Builder {
method new (line 116) | pub fn new(target_addr: IpAddr) -> Self {
method source_addr (line 142) | pub fn source_addr(self, source_addr: Option<IpAddr>) -> Self {
method interface (line 170) | pub fn interface<S: Into<String>>(self, interface: Option<S>) -> Self {
method protocol (line 192) | pub fn protocol(self, protocol: Protocol) -> Self {
method trace_identifier (line 211) | pub fn trace_identifier(self, trace_id: u16) -> Self {
method privilege_mode (line 235) | pub fn privilege_mode(self, privilege_mode: PrivilegeMode) -> Self {
method multipath_strategy (line 259) | pub fn multipath_strategy(self, multipath_strategy: MultipathStrategy)...
method packet_size (line 281) | pub fn packet_size(self, packet_size: u16) -> Self {
method payload_pattern (line 303) | pub fn payload_pattern(self, payload_pattern: u8) -> Self {
method tos (line 325) | pub fn tos(self, tos: u8) -> Self {
method icmp_extension_parse_mode (line 349) | pub fn icmp_extension_parse_mode(
method read_timeout (line 377) | pub fn read_timeout(self, read_timeout: Duration) -> Self {
method tcp_connect_timeout (line 402) | pub fn tcp_connect_timeout(self, tcp_connect_timeout: Duration) -> Self {
method max_rounds (line 427) | pub fn max_rounds(self, max_rounds: Option<usize>) -> Self {
method first_ttl (line 450) | pub fn first_ttl(self, first_ttl: u8) -> Self {
method max_ttl (line 472) | pub fn max_ttl(self, max_ttl: u8) -> Self {
method grace_duration (line 497) | pub fn grace_duration(self, grace_duration: Duration) -> Self {
method max_inflight (line 519) | pub fn max_inflight(self, max_inflight: u8) -> Self {
method initial_sequence (line 541) | pub fn initial_sequence(self, initial_sequence: u16) -> Self {
method port_direction (line 565) | pub fn port_direction(self, port_direction: PortDirection) -> Self {
method min_round_duration (line 590) | pub fn min_round_duration(self, min_round_duration: Duration) -> Self {
method max_round_duration (line 615) | pub fn max_round_duration(self, max_round_duration: Duration) -> Self {
method max_samples (line 637) | pub fn max_samples(self, max_samples: usize) -> Self {
method max_flows (line 659) | pub fn max_flows(self, max_flows: usize) -> Self {
method drop_privileges (line 678) | pub fn drop_privileges(self, drop_privileges: bool) -> Self {
method build (line 703) | pub fn build(self) -> Result<Tracer> {
method default (line 68) | fn default() -> Self {
constant SOURCE_ADDR (line 773) | const SOURCE_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED);
constant TARGET_ADDR (line 774) | const TARGET_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::new(2, 2, 2, 2));
function test_builder_minimal (line 777) | fn test_builder_minimal() {
function test_builder_full (line 839) | fn test_builder_full() {
function test_zero_max_rounds (line 901) | fn test_zero_max_rounds() {
function test_invalid_initial_sequence (line 910) | fn test_invalid_initial_sequence() {
FILE: crates/trippy-core/src/config.rs
constant DEFAULT_PRIVILEGE_MODE (line 17) | pub const DEFAULT_PRIVILEGE_MODE: PrivilegeMode = PrivilegeMode::Privile...
constant DEFAULT_STRATEGY_PROTOCOL (line 20) | pub const DEFAULT_STRATEGY_PROTOCOL: Protocol = Protocol::Icmp;
constant DEFAULT_STRATEGY_MULTIPATH (line 23) | pub const DEFAULT_STRATEGY_MULTIPATH: MultipathStrategy = MultipathStrat...
constant DEFAULT_ICMP_EXTENSION_PARSE_MODE (line 26) | pub const DEFAULT_ICMP_EXTENSION_PARSE_MODE: IcmpExtensionParseMode =
constant DEFAULT_STRATEGY_MAX_INFLIGHT (line 30) | pub const DEFAULT_STRATEGY_MAX_INFLIGHT: u8 = 24;
constant DEFAULT_STRATEGY_FIRST_TTL (line 33) | pub const DEFAULT_STRATEGY_FIRST_TTL: u8 = 1;
constant DEFAULT_STRATEGY_MAX_TTL (line 36) | pub const DEFAULT_STRATEGY_MAX_TTL: u8 = 64;
constant DEFAULT_STRATEGY_PACKET_SIZE (line 39) | pub const DEFAULT_STRATEGY_PACKET_SIZE: u16 = 84;
constant DEFAULT_STRATEGY_PAYLOAD_PATTERN (line 42) | pub const DEFAULT_STRATEGY_PAYLOAD_PATTERN: u8 = 0;
constant DEFAULT_STRATEGY_MIN_ROUND_DURATION (line 45) | pub const DEFAULT_STRATEGY_MIN_ROUND_DURATION: Duration = Duration::from...
constant DEFAULT_STRATEGY_MAX_ROUND_DURATION (line 48) | pub const DEFAULT_STRATEGY_MAX_ROUND_DURATION: Duration = Duration::from...
constant DEFAULT_STRATEGY_INITIAL_SEQUENCE (line 51) | pub const DEFAULT_STRATEGY_INITIAL_SEQUENCE: u16 = 33434;
constant DEFAULT_STRATEGY_TOS (line 54) | pub const DEFAULT_STRATEGY_TOS: u8 = 0;
constant DEFAULT_STRATEGY_READ_TIMEOUT (line 57) | pub const DEFAULT_STRATEGY_READ_TIMEOUT: Duration = Duration::from_milli...
constant DEFAULT_STRATEGY_GRACE_DURATION (line 60) | pub const DEFAULT_STRATEGY_GRACE_DURATION: Duration = Duration::from_mil...
constant DEFAULT_STRATEGY_TCP_CONNECT_TIMEOUT (line 63) | pub const DEFAULT_STRATEGY_TCP_CONNECT_TIMEOUT: Duration = Duration::fro...
constant DEFAULT_MAX_SAMPLES (line 66) | pub const DEFAULT_MAX_SAMPLES: usize = 256;
constant DEFAULT_MAX_FLOWS (line 69) | pub const DEFAULT_MAX_FLOWS: usize = 64;
type PrivilegeMode (line 74) | pub enum PrivilegeMode {
method is_unprivileged (line 83) | pub const fn is_unprivileged(self) -> bool {
method fmt (line 92) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type IcmpExtensionParseMode (line 102) | pub enum IcmpExtensionParseMode {
method is_enabled (line 111) | pub const fn is_enabled(self) -> bool {
method fmt (line 120) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type Protocol (line 130) | pub enum Protocol {
method fmt (line 140) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type MultipathStrategy (line 151) | pub enum MultipathStrategy {
method fmt (line 184) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type PortDirection (line 195) | pub enum PortDirection {
method new_fixed_src (line 218) | pub const fn new_fixed_src(src: u16) -> Self {
method new_fixed_dest (line 223) | pub const fn new_fixed_dest(dest: u16) -> Self {
method new_fixed_both (line 228) | pub const fn new_fixed_both(src: u16, dest: u16) -> Self {
method src (line 233) | pub const fn src(&self) -> Option<Port> {
method dest (line 240) | pub const fn dest(&self) -> Option<Port> {
type StateConfig (line 250) | pub struct StateConfig {
method default (line 264) | fn default() -> Self {
type ChannelConfig (line 274) | pub struct ChannelConfig {
method default (line 289) | fn default() -> Self {
type StrategyConfig (line 308) | pub struct StrategyConfig {
method default (line 325) | fn default() -> Self {
FILE: crates/trippy-core/src/constants.rs
constant MAX_TTL (line 5) | pub const MAX_TTL: u8 = 254;
constant MAX_SEQUENCE_PER_ROUND (line 12) | pub const MAX_SEQUENCE_PER_ROUND: u16 = 512;
constant MAX_INITIAL_SEQUENCE (line 19) | pub const MAX_INITIAL_SEQUENCE: u16 = u16::MAX - (MAX_SEQUENCE_PER_ROUND...
FILE: crates/trippy-core/src/error.rs
type Result (line 7) | pub type Result<T> = std::result::Result<T, Error>;
type Error (line 11) | pub enum Error {
type IoResult (line 39) | pub type IoResult<T> = std::result::Result<T, IoError>;
type IoError (line 43) | pub enum IoError {
method kind (line 56) | pub fn kind(&self) -> ErrorKind {
type ErrorKind (line 69) | pub enum ErrorKind {
type IoOperation (line 78) | pub enum IoOperation {
method fmt (line 108) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
FILE: crates/trippy-core/src/flows.rs
type FlowId (line 23) | pub struct FlowId(pub u64);
method fmt (line 26) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type FlowRegistry (line 33) | pub struct FlowRegistry {
method new (line 42) | pub const fn new() -> Self {
method register (line 62) | pub fn register(&mut self, flow: Flow) -> FlowId {
method flows (line 83) | pub fn flows(&self) -> &[(Flow, FlowId)] {
type Flow (line 90) | pub struct Flow {
method from_hops (line 100) | pub fn from_hops(hops: impl IntoIterator<Item = Option<IpAddr>>) -> Se...
method check (line 129) | pub fn check(&self, flow: &Self) -> CheckStatus {
method merge (line 149) | fn merge(&mut self, flow: &Self) {
method fmt (line 167) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type CheckStatus (line 174) | pub enum CheckStatus {
type FlowEntry (line 185) | pub enum FlowEntry {
method fmt (line 193) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_single_flow (line 210) | fn test_single_flow() {
function test_two_different_flows (line 222) | fn test_two_different_flows() {
function test_two_same_flows (line 234) | fn test_two_same_flows() {
function test_two_same_one_different_flows (line 246) | fn test_two_same_one_different_flows() {
function test_merge_flow1 (line 261) | fn test_merge_flow1() {
function test_merge_flow2 (line 281) | fn test_merge_flow2() {
function test_merge_flow3 (line 298) | fn test_merge_flow3() {
function test_subset (line 324) | fn test_subset() {
function test_subset_any (line 335) | fn test_subset_any() {
function test_superset (line 346) | fn test_superset() {
function test_superset_any (line 357) | fn test_superset_any() {
function test_start_any_then_same_flows (line 368) | fn test_start_any_then_same_flows() {
function test_start_any_then_diff_flows (line 379) | fn test_start_any_then_diff_flows() {
function addr (line 390) | fn addr(addr: &str) -> Option<IpAddr> {
FILE: crates/trippy-core/src/net.rs
type Network (line 33) | pub trait Network {
method send_probe (line 35) | fn send_probe(&mut self, probe: Probe) -> Result<()>;
method recv_probe (line 40) | fn recv_probe(&mut self) -> Result<Option<Response>>;
FILE: crates/trippy-core/src/net/channel.rs
constant MAX_PACKET_SIZE (line 13) | pub const MAX_PACKET_SIZE: usize = 1024;
constant MAX_TCP_PROBES (line 16) | const MAX_TCP_PROBES: usize = 256;
type Channel (line 19) | pub struct Channel<S: Socket> {
type FamilyConfig (line 30) | enum FamilyConfig {
function connect (line 40) | pub fn connect(config: &ChannelConfig) -> Result<Self> {
method send_probe (line 93) | fn send_probe(&mut self, probe: Probe) -> Result<()> {
method recv_probe (line 102) | fn recv_probe(&mut self) -> Result<Option<Response>> {
function dispatch_icmp_probe (line 120) | fn dispatch_icmp_probe(&mut self, probe: &Probe) -> Result<()> {
function dispatch_udp_probe (line 130) | fn dispatch_udp_probe(&mut self, probe: &Probe) -> Result<()> {
function dispatch_tcp_probe (line 140) | fn dispatch_tcp_probe(&mut self, probe: &Probe) -> Result<()> {
function recv_icmp_probe (line 156) | fn recv_icmp_probe(&mut self) -> Result<Option<Response>> {
function recv_tcp_sockets (line 172) | fn recv_tcp_sockets(&mut self) -> Result<Option<Response>> {
type TcpProbe (line 203) | struct TcpProbe<S: Socket> {
function new (line 211) | pub const fn new(socket: S, src_port: Port, dest_port: Port, start: Syst...
function make_icmp_send_socket (line 223) | fn make_icmp_send_socket<S: Socket>(addr: IpAddr, raw: bool) -> Result<S> {
function make_udp_send_socket (line 232) | fn make_udp_send_socket<S: Socket>(addr: IpAddr, raw: bool) -> Result<S> {
function make_recv_socket (line 241) | fn make_recv_socket<S: Socket>(addr: IpAddr, raw: bool) -> Result<S> {
FILE: crates/trippy-core/src/net/common.rs
type ErrorMapper (line 6) | pub struct ErrorMapper;
method in_progress (line 10) | pub fn in_progress(err: Error) -> Result<()> {
method addr_in_use (line 22) | pub fn addr_in_use(err: Error, addr: SocketAddr) -> Error {
method probe_failed (line 34) | pub fn probe_failed(err: Error, kind: ErrorKind) -> Error {
constant ADDR (line 49) | const ADDR: SocketAddr = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::UNSP...
function test_in_progress (line 52) | fn test_in_progress() {
function test_not_in_progress (line 59) | fn test_not_in_progress() {
function test_addr_in_use (line 66) | fn test_addr_in_use() {
function test_not_addr_in_use (line 74) | fn test_not_addr_in_use() {
function test_probe_failed (line 82) | fn test_probe_failed() {
FILE: crates/trippy-core/src/net/extension.rs
constant ICMP_EXTENSION_VERSION (line 10) | const ICMP_EXTENSION_VERSION: u8 = 2;
type Error (line 13) | type Error = Error;
method try_from (line 15) | fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
type Error (line 21) | type Error = Error;
method try_from (line 23) | fn try_from(value: ExtensionsPacket<'_>) -> Result<Self, Self::Error> {
method from (line 44) | fn from(value: MplsLabelStackPacket<'_>) -> Self {
method from (line 56) | fn from(value: MplsLabelStackMemberPacket<'_>) -> Self {
method from (line 67) | fn from(value: ExtensionObjectPacket<'_>) -> Self {
function test_convert_mpls_extensions (line 82) | fn test_convert_mpls_extensions() {
function test_convert_unknown_extensions (line 104) | fn test_convert_unknown_extensions() {
function test_convert_unknown_version (line 123) | fn test_convert_unknown_version() {
FILE: crates/trippy-core/src/net/ipv4.rs
constant MAX_UDP_PACKET_BUF (line 29) | const MAX_UDP_PACKET_BUF: usize = MAX_PACKET_SIZE - Ipv4Packet::minimum_...
constant MAX_UDP_PAYLOAD_BUF (line 32) | const MAX_UDP_PAYLOAD_BUF: usize = MAX_UDP_PACKET_BUF - UdpPacket::minim...
constant MAX_ICMP_PACKET_BUF (line 35) | const MAX_ICMP_PACKET_BUF: usize = MAX_PACKET_SIZE - Ipv4Packet::minimum...
constant MAX_ICMP_PAYLOAD_BUF (line 38) | const MAX_ICMP_PAYLOAD_BUF: usize = MAX_ICMP_PACKET_BUF - IcmpPacket::mi...
constant MIN_PACKET_SIZE_ICMP (line 41) | const MIN_PACKET_SIZE_ICMP: usize =
constant MIN_PACKET_SIZE_UDP (line 45) | const MIN_PACKET_SIZE_UDP: usize =
constant DONT_FRAGMENT (line 51) | const DONT_FRAGMENT: u16 = 0x4000;
type Ipv4 (line 55) | pub struct Ipv4 {
method dispatch_icmp_probe (line 86) | pub fn dispatch_icmp_probe<S: Socket>(
method dispatch_udp_probe (line 122) | pub fn dispatch_udp_probe<S: Socket>(
method dispatch_udp_probe_raw (line 146) | fn dispatch_udp_probe_raw<S: Socket>(
method dispatch_udp_probe_non_raw (line 186) | fn dispatch_udp_probe_non_raw<S: Socket>(&self, probe: &Probe, payload...
method dispatch_tcp_probe (line 204) | pub fn dispatch_tcp_probe<S: Socket>(&self, probe: &Probe) -> Result<S> {
method recv_icmp_probe (line 227) | pub fn recv_icmp_probe<S: Socket>(&self, recv_socket: &mut S) -> Resul...
method recv_tcp_socket (line 243) | pub fn recv_tcp_socket<S: Socket>(
method extract_probe_resp (line 288) | fn extract_probe_resp(&self, ipv4: &Ipv4Packet<'_>) -> Result<Option<R...
method extract_probe_proto_resp (line 358) | fn extract_probe_proto_resp(&self, ipv4: &Ipv4Packet<'_>) -> Result<Op...
method make_echo_request_icmp_packet (line 401) | fn make_echo_request_icmp_packet<'a>(
method make_udp_packet (line 421) | fn make_udp_packet<'a>(
method make_ipv4_packet (line 443) | fn make_ipv4_packet<'a>(
method calc_udp_checksum (line 474) | pub fn calc_udp_checksum(
method default (line 68) | fn default() -> Self {
constant ADDR_NOT_AVAILABLE_KIND (line 488) | const ADDR_NOT_AVAILABLE_KIND: ErrorKind = ErrorKind::Std(io::ErrorKind:...
constant INVALID_INPUT_KIND (line 489) | const INVALID_INPUT_KIND: ErrorKind = ErrorKind::Std(io::ErrorKind::Inva...
function icmp_payload_size (line 491) | const fn icmp_payload_size(packet_size: usize) -> usize {
function udp_payload_size (line 497) | const fn udp_payload_size(packet_size: usize) -> usize {
function extract_echo_request (line 504) | fn extract_echo_request<'a>(ipv4: &'a Ipv4Packet<'a>) -> Result<EchoRequ...
function extract_udp_packet (line 510) | fn extract_udp_packet(ipv4: &Ipv4Packet<'_>) -> Result<(u16, u16, u16, u...
function extract_tcp_packet (line 533) | fn extract_tcp_packet(ipv4: &Ipv4Packet<'_>) -> Result<(u16, u16)> {
function test_dispatch_icmp_probe_no_payload (line 561) | fn test_dispatch_icmp_probe_no_payload() -> anyhow::Result<()> {
function test_dispatch_icmp_probe_with_payload (line 599) | fn test_dispatch_icmp_probe_with_payload() -> anyhow::Result<()> {
function test_dispatch_icmp_probe_invalid_packet_size_low (line 638) | fn test_dispatch_icmp_probe_invalid_packet_size_low() -> anyhow::Result<...
function test_dispatch_icmp_probe_invalid_packet_size_high (line 660) | fn test_dispatch_icmp_probe_invalid_packet_size_high() -> anyhow::Result...
function test_dispatch_icmp_probe_with_tos (line 682) | fn test_dispatch_icmp_probe_with_tos() -> anyhow::Result<()> {
function test_dispatch_udp_probe_classic_privileged_no_payload (line 722) | fn test_dispatch_udp_probe_classic_privileged_no_payload() -> anyhow::Re...
function test_dispatch_udp_probe_classic_privileged_with_payload (line 762) | fn test_dispatch_udp_probe_classic_privileged_with_payload() -> anyhow::...
function test_dispatch_udp_probe_paris_privileged (line 803) | fn test_dispatch_udp_probe_paris_privileged() -> anyhow::Result<()> {
function test_dispatch_udp_probe_dublin_privileged (line 848) | fn test_dispatch_udp_probe_dublin_privileged() -> anyhow::Result<()> {
function test_dispatch_udp_probe_classic_unprivileged_no_payload (line 893) | fn test_dispatch_udp_probe_classic_unprivileged_no_payload() -> anyhow::...
function test_dispatch_udp_probe_classic_unprivileged_with_payload (line 956) | fn test_dispatch_udp_probe_classic_unprivileged_with_payload() -> anyhow...
function test_dispatch_udp_probe_classic_privileged_with_tos (line 1019) | fn test_dispatch_udp_probe_classic_privileged_with_tos() -> anyhow::Resu...
function test_dispatch_udp_probe_classic_unprivileged_with_tos (line 1061) | fn test_dispatch_udp_probe_classic_unprivileged_with_tos() -> anyhow::Re...
function test_dispatch_udp_probe_invalid_packet_size_low (line 1126) | fn test_dispatch_udp_probe_invalid_packet_size_low() -> anyhow::Result<(...
function test_dispatch_udp_probe_invalid_packet_size_high (line 1150) | fn test_dispatch_udp_probe_invalid_packet_size_high() -> anyhow::Result<...
function test_dispatch_tcp_probe (line 1174) | fn test_dispatch_tcp_probe() -> anyhow::Result<()> {
function test_recv_icmp_probe_echo_reply (line 1226) | fn test_recv_icmp_probe_echo_reply() -> anyhow::Result<()> {
function test_recv_icmp_probe_time_exceeded_icmp_no_extensions (line 1274) | fn test_recv_icmp_probe_time_exceeded_icmp_no_extensions() -> anyhow::Re...
function test_recv_icmp_probe_destination_unreachable_icmp_no_extensions (line 1325) | fn test_recv_icmp_probe_destination_unreachable_icmp_no_extensions() -> ...
function test_recv_icmp_probe_time_exceeded_udp_no_extensions (line 1373) | fn test_recv_icmp_probe_time_exceeded_udp_no_extensions() -> anyhow::Res...
function test_recv_icmp_probe_destination_unreachable_udp_no_extensions (line 1441) | fn test_recv_icmp_probe_destination_unreachable_udp_no_extensions() -> a...
function test_recv_icmp_probe_time_exceeded_tcp_no_extensions (line 1506) | fn test_recv_icmp_probe_time_exceeded_tcp_no_extensions() -> anyhow::Res...
function test_recv_icmp_probe_destination_unreachable_tcp_no_extensions (line 1561) | fn test_recv_icmp_probe_destination_unreachable_tcp_no_extensions() -> a...
function test_recv_icmp_probe_wrong_icmp_original_datagram_type_ignored (line 1613) | fn test_recv_icmp_probe_wrong_icmp_original_datagram_type_ignored() -> a...
function test_recv_icmp_probe_wrong_udp_original_datagram_type_ignored (line 1658) | fn test_recv_icmp_probe_wrong_udp_original_datagram_type_ignored() -> an...
function test_recv_icmp_probe_wrong_tcp_original_datagram_type_ignored (line 1703) | fn test_recv_icmp_probe_wrong_tcp_original_datagram_type_ignored() -> an...
function test_recv_tcp_socket_tcp_reply (line 1747) | fn test_recv_tcp_socket_tcp_reply() -> anyhow::Result<()> {
function test_recv_tcp_socket_tcp_refused (line 1789) | fn test_recv_tcp_socket_tcp_refused() -> anyhow::Result<()> {
function test_recv_tcp_socket_tcp_host_unreachable (line 1828) | fn test_recv_tcp_socket_tcp_host_unreachable() -> anyhow::Result<()> {
function test_icmp_time_exceeded_fragment_reassembly_ignored (line 1882) | fn test_icmp_time_exceeded_fragment_reassembly_ignored() -> anyhow::Resu...
function test_recv_icmp_probe_udp_wrong_payload_size (line 1918) | fn test_recv_icmp_probe_udp_wrong_payload_size() -> anyhow::Result<()> {
function make_icmp_probe (line 1985) | fn make_icmp_probe() -> Probe {
function make_udp_probe (line 1998) | fn make_udp_probe(src_port: u16, dest_port: u16) -> Probe {
FILE: crates/trippy-core/src/net/ipv6.rs
constant MAX_UDP_PACKET_BUF (line 28) | const MAX_UDP_PACKET_BUF: usize = MAX_PACKET_SIZE - Ipv6Packet::minimum_...
constant MAX_UDP_PAYLOAD_BUF (line 31) | const MAX_UDP_PAYLOAD_BUF: usize = MAX_UDP_PACKET_BUF - UdpPacket::minim...
constant MAX_ICMP_PACKET_BUF (line 34) | const MAX_ICMP_PACKET_BUF: usize = MAX_PACKET_SIZE - Ipv6Packet::minimum...
constant MAX_ICMP_PAYLOAD_BUF (line 37) | const MAX_ICMP_PAYLOAD_BUF: usize = MAX_ICMP_PACKET_BUF - IcmpPacket::mi...
constant MIN_PACKET_SIZE_ICMP (line 40) | const MIN_PACKET_SIZE_ICMP: usize =
constant MIN_PACKET_SIZE_UDP (line 44) | const MIN_PACKET_SIZE_UDP: usize =
constant MAGIC (line 48) | const MAGIC: &[u8] = b"trippy";
type Ipv6 (line 52) | pub struct Ipv6 {
method dispatch_icmp_probe (line 83) | pub fn dispatch_icmp_probe<S: Socket>(
method dispatch_udp_probe (line 108) | pub fn dispatch_udp_probe<S: Socket>(
method dispatch_udp_probe_raw (line 128) | fn dispatch_udp_probe_raw<S: Socket>(
method dispatch_udp_probe_non_raw (line 165) | fn dispatch_udp_probe_non_raw<S: Socket>(&self, probe: &Probe, payload...
method dispatch_tcp_probe (line 182) | pub fn dispatch_tcp_probe<S: Socket>(&self, probe: &Probe) -> Result<S> {
method recv_icmp_probe (line 203) | pub fn recv_icmp_probe<S: Socket>(&self, recv_socket: &mut S) -> Resul...
method recv_tcp_socket (line 223) | pub fn recv_tcp_socket<S: Socket>(
method extract_probe_resp (line 267) | fn extract_probe_resp(
method extract_probe_proto_resp (line 339) | fn extract_probe_proto_resp(&self, ipv6: &Ipv6Packet<'_>) -> Result<Op...
method make_udp_packet (line 384) | fn make_udp_packet<'a>(
method make_echo_request_icmp_packet (line 406) | fn make_echo_request_icmp_packet<'a>(
method default (line 65) | fn default() -> Self {
function icmp_payload_size (line 430) | const fn icmp_payload_size(packet_size: usize) -> usize {
function udp_payload_size (line 436) | const fn udp_payload_size(packet_size: usize) -> usize {
function extract_echo_request (line 442) | fn extract_echo_request(ipv6: &Ipv6Packet<'_>) -> Result<(u16, u16)> {
function extract_udp_packet (line 450) | fn extract_udp_packet(ipv6: &Ipv6Packet<'_>) -> Result<(u16, u16, u16, u...
function extract_tcp_packet (line 479) | fn extract_tcp_packet(ipv6: &Ipv6Packet<'_>) -> Result<(u16, u16)> {
function udp_payload_has_magic_prefix (line 484) | fn udp_payload_has_magic_prefix(ipv6: &Ipv6Packet<'_>) -> Result<bool> {
function test_dispatch_icmp_probe_no_payload (line 504) | fn test_dispatch_icmp_probe_no_payload() -> anyhow::Result<()> {
function test_dispatch_icmp_probe_with_payload (line 544) | fn test_dispatch_icmp_probe_with_payload() -> anyhow::Result<()> {
function test_dispatch_icmp_probe_invalid_packet_size_low (line 589) | fn test_dispatch_icmp_probe_invalid_packet_size_low() -> anyhow::Result<...
function test_dispatch_icmp_probe_invalid_packet_size_high (line 609) | fn test_dispatch_icmp_probe_invalid_packet_size_high() -> anyhow::Result...
function test_dispatch_udp_probe_classic_privileged_no_payload (line 629) | fn test_dispatch_udp_probe_classic_privileged_no_payload() -> anyhow::Re...
function test_dispatch_udp_probe_classic_privileged_with_payload (line 674) | fn test_dispatch_udp_probe_classic_privileged_with_payload() -> anyhow::...
function test_dispatch_udp_probe_paris_privileged (line 723) | fn test_dispatch_udp_probe_paris_privileged() -> anyhow::Result<()> {
function test_dispatch_udp_probe_dublin_privileged (line 780) | fn test_dispatch_udp_probe_dublin_privileged() -> anyhow::Result<()> {
function test_dispatch_udp_probe_classic_unprivileged_no_payload (line 837) | fn test_dispatch_udp_probe_classic_unprivileged_no_payload() -> anyhow::...
function test_dispatch_udp_probe_classic_unprivileged_with_payload (line 900) | fn test_dispatch_udp_probe_classic_unprivileged_with_payload() -> anyhow...
function test_dispatch_udp_probe_invalid_packet_size_low (line 963) | fn test_dispatch_udp_probe_invalid_packet_size_low() -> anyhow::Result<(...
function test_dispatch_udp_probe_invalid_packet_size_high (line 987) | fn test_dispatch_udp_probe_invalid_packet_size_high() -> anyhow::Result<...
function test_dispatch_tcp_probe (line 1011) | fn test_dispatch_tcp_probe() -> anyhow::Result<()> {
function test_recv_icmp_probe_echo_reply (line 1060) | fn test_recv_icmp_probe_echo_reply() -> anyhow::Result<()> {
function test_recv_icmp_probe_time_exceeded_icmp_no_extensions (line 1110) | fn test_recv_icmp_probe_time_exceeded_icmp_no_extensions() -> anyhow::Re...
function test_recv_icmp_probe_destination_unreachable_icmp_no_extensions (line 1165) | fn test_recv_icmp_probe_destination_unreachable_icmp_no_extensions() -> ...
function test_recv_icmp_probe_time_exceeded_udp_no_extensions (line 1220) | fn test_recv_icmp_probe_time_exceeded_udp_no_extensions() -> anyhow::Res...
function test_recv_icmp_probe_destination_unreachable_udp_no_extensions (line 1287) | fn test_recv_icmp_probe_destination_unreachable_udp_no_extensions() -> a...
function test_recv_icmp_probe_time_exceeded_udp_dublin_with_magic (line 1364) | fn test_recv_icmp_probe_time_exceeded_udp_dublin_with_magic() -> anyhow:...
function test_recv_icmp_probe_time_exceeded_tcp_no_extensions (line 1433) | fn test_recv_icmp_probe_time_exceeded_tcp_no_extensions() -> anyhow::Res...
function test_recv_icmp_probe_destination_unreachable_tcp_no_extensions (line 1493) | fn test_recv_icmp_probe_destination_unreachable_tcp_no_extensions() -> a...
function test_recv_icmp_probe_wrong_icmp_original_datagram_type_ignored (line 1553) | fn test_recv_icmp_probe_wrong_icmp_original_datagram_type_ignored() -> a...
function test_recv_icmp_probe_wrong_udp_original_datagram_type_ignored (line 1602) | fn test_recv_icmp_probe_wrong_udp_original_datagram_type_ignored() -> an...
function test_recv_icmp_probe_wrong_tcp_original_datagram_type_ignored (line 1651) | fn test_recv_icmp_probe_wrong_tcp_original_datagram_type_ignored() -> an...
function test_recv_tcp_socket_tcp_reply (line 1700) | fn test_recv_tcp_socket_tcp_reply() -> anyhow::Result<()> {
function test_recv_tcp_socket_tcp_refused (line 1742) | fn test_recv_tcp_socket_tcp_refused() -> anyhow::Result<()> {
function test_recv_tcp_socket_tcp_host_unreachable (line 1781) | fn test_recv_tcp_socket_tcp_host_unreachable() -> anyhow::Result<()> {
function test_icmp_time_exceeded_fragment_reassembly_ignored (line 1835) | fn test_icmp_time_exceeded_fragment_reassembly_ignored() -> anyhow::Resu...
function make_icmp_probe (line 1869) | fn make_icmp_probe() -> Probe {
function make_udp_probe (line 1882) | fn make_udp_probe(src_port: u16, dest_port: u16) -> Probe {
FILE: crates/trippy-core/src/net/platform.rs
type Platform (line 21) | pub trait Platform {
method byte_order_for_address (line 23) | fn byte_order_for_address(addr: IpAddr) -> Result<Ipv4ByteOrder>;
method lookup_interface_addr (line 29) | fn lookup_interface_addr(addr: IpAddr, name: &str) -> Result<IpAddr>;
method discover_local_addr (line 32) | fn discover_local_addr(target_addr: IpAddr, port: u16) -> Result<IpAddr>;
FILE: crates/trippy-core/src/net/platform/byte_order.rs
type Ipv4ByteOrder (line 18) | pub enum Ipv4ByteOrder {
method for_address (line 51) | pub fn for_address(addr: IpAddr) -> Result<Self> {
method adjust_length (line 57) | pub const fn adjust_length(self, ipv4_total_length: u16) -> u16 {
FILE: crates/trippy-core/src/net/platform/unix.rs
type PlatformImpl (line 5) | pub struct PlatformImpl;
method byte_order_for_address (line 8) | fn byte_order_for_address(addr: IpAddr) -> Result<Ipv4ByteOrder> {
method lookup_interface_addr (line 11) | fn lookup_interface_addr(addr: IpAddr, name: &str) -> Result<IpAddr> {
method discover_local_addr (line 14) | fn discover_local_addr(target_addr: IpAddr, port: u16) -> Result<IpAddr> {
constant TEST_PACKET_LENGTH (line 33) | const TEST_PACKET_LENGTH: u16 = 256;
function for_address (line 42) | pub const fn for_address(_src_addr: IpAddr) -> Result<Ipv4ByteOrder> {
function for_address (line 48) | pub fn for_address(addr: IpAddr) -> Result<Ipv4ByteOrder> {
function test_send_local_ip4_packet (line 76) | fn test_send_local_ip4_packet(src_addr: Ipv4Addr, total_length: u16) -> ...
function lookup_interface_addr (line 103) | pub fn lookup_interface_addr(addr: IpAddr, name: &str) -> Result<IpAddr> {
function lookup_interface_addr_ipv4 (line 111) | fn lookup_interface_addr_ipv4(name: &str) -> Result<IpAddr> {
function lookup_interface_addr_ipv6 (line 126) | fn lookup_interface_addr_ipv6(name: &str) -> Result<IpAddr> {
function discover_local_addr (line 142) | pub fn discover_local_addr(target_addr: IpAddr, port: u16) -> Result<IpA...
function startup (line 172) | pub fn startup() -> Result<()> {
type SocketImpl (line 177) | pub struct SocketImpl {
method new (line 182) | fn new(domain: Domain, ty: Type, protocol: Protocol) -> IoResult<Self> {
method new_raw_ipv4 (line 189) | pub(super) fn new_raw_ipv4(protocol: Protocol) -> IoResult<Self> {
method new_raw_ipv6 (line 196) | fn new_raw_ipv6(protocol: Protocol) -> IoResult<Self> {
method new_dgram_ipv4 (line 203) | pub(super) fn new_dgram_ipv4(protocol: Protocol) -> IoResult<Self> {
method new_dgram_ipv6 (line 210) | fn new_dgram_ipv6(protocol: Protocol) -> IoResult<Self> {
method set_nonblocking (line 217) | fn set_nonblocking(&self, nonblocking: bool) -> IoResult<()> {
method local_addr (line 223) | pub(super) fn local_addr(&self) -> IoResult<Option<SocketAddr>> {
method new_icmp_send_socket_ipv4 (line 234) | fn new_icmp_send_socket_ipv4(raw: bool) -> IoResult<Self> {
method new_icmp_send_socket_ipv6 (line 248) | fn new_icmp_send_socket_ipv6(raw: bool) -> IoResult<Self> {
method new_udp_send_socket_ipv4 (line 260) | fn new_udp_send_socket_ipv4(raw: bool) -> IoResult<Self> {
method new_udp_send_socket_ipv6 (line 273) | fn new_udp_send_socket_ipv6(raw: bool) -> IoResult<Self> {
method new_recv_socket_ipv4 (line 285) | fn new_recv_socket_ipv4(_: Ipv4Addr, raw: bool) -> IoResult<Self> {
method new_recv_socket_ipv6 (line 298) | fn new_recv_socket_ipv6(_: Ipv6Addr, raw: bool) -> IoResult<Self> {
method new_stream_socket_ipv4 (line 310) | fn new_stream_socket_ipv4() -> IoResult<Self> {
method new_stream_socket_ipv6 (line 317) | fn new_stream_socket_ipv6() -> IoResult<Self> {
method new_udp_dgram_socket_ipv4 (line 324) | fn new_udp_dgram_socket_ipv4() -> IoResult<Self> {
method new_udp_dgram_socket_ipv6 (line 328) | fn new_udp_dgram_socket_ipv6() -> IoResult<Self> {
method bind (line 332) | fn bind(&mut self, address: SocketAddr) -> IoResult<()> {
method set_tos (line 338) | fn set_tos(&mut self, tos: u32) -> IoResult<()> {
method set_tclass_v6 (line 344) | fn set_tclass_v6(&mut self, tclass: u32) -> IoResult<()> {
method set_ttl (line 350) | fn set_ttl(&mut self, ttl: u32) -> IoResult<()> {
method set_reuse_port (line 356) | fn set_reuse_port(&mut self, reuse: bool) -> IoResult<()> {
method set_header_included (line 362) | fn set_header_included(&mut self, included: bool) -> IoResult<()> {
method set_unicast_hops_v6 (line 368) | fn set_unicast_hops_v6(&mut self, hops: u8) -> IoResult<()> {
method connect (line 374) | fn connect(&mut self, address: SocketAddr) -> IoResult<()> {
method send_to (line 381) | fn send_to(&mut self, buf: &[u8], addr: SocketAddr) -> IoResult<()> {
method is_readable (line 389) | fn is_readable(&mut self, timeout: Duration) -> IoResult<bool> {
method is_writable (line 409) | fn is_writable(&mut self) -> IoResult<bool> {
method recv_from (line 429) | fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(usize, Option<Socke...
method read (line 442) | fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
method shutdown (line 454) | fn shutdown(&mut self) -> IoResult<()> {
method peer_addr (line 460) | fn peer_addr(&mut self) -> IoResult<Option<SocketAddr>> {
method take_error (line 470) | fn take_error(&mut self) -> IoResult<Option<SocketError>> {
method icmp_error_info (line 484) | fn icmp_error_info(&mut self) -> IoResult<IpAddr> {
method from (line 490) | fn from(value: &io::Error) -> Self {
function from (line 505) | fn from(value: ErrorKind) -> Self {
method read (line 516) | fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
type RecvFrom (line 526) | trait RecvFrom {
method recv_from_into_buf (line 527) | fn recv_from_into_buf(&self, buf: &mut [u8]) -> io::Result<(usize, Opt...
method recv_from_into_buf (line 534) | fn recv_from_into_buf(&self, buf: &mut [u8]) -> io::Result<(usize, Opt...
FILE: crates/trippy-core/src/net/platform/windows.rs
type PlatformImpl (line 65) | pub struct PlatformImpl;
method byte_order_for_address (line 68) | fn byte_order_for_address(_addr: IpAddr) -> Result<Ipv4ByteOrder> {
method lookup_interface_addr (line 72) | fn lookup_interface_addr(addr: IpAddr, name: &str) -> Result<IpAddr> {
method discover_local_addr (line 79) | fn discover_local_addr(target_addr: IpAddr, _port: u16) -> Result<IpAddr> {
function startup (line 85) | pub fn startup() -> Result<()> {
constant WINSOCK_VERSION (line 90) | const WINSOCK_VERSION: u16 = 0x202;
type SocketImpl (line 93) | pub struct SocketImpl {
method startup (line 104) | fn startup() -> IoResult<()> {
method new (line 113) | fn new(domain: Domain, ty: Type, protocol: Option<Protocol>) -> IoResu...
method create_event (line 131) | fn create_event(&mut self) -> IoResult<()> {
method wait_for_event (line 138) | fn wait_for_event(&self, timeout: Duration) -> IoResult<bool> {
method reset_event (line 153) | fn reset_event(&self) -> IoResult<()> {
method getsockopt (line 160) | fn getsockopt<T>(&self, level: i32, optname: i32, mut optval: T) -> St...
method setsockopt_u32 (line 176) | fn setsockopt_u32(&self, level: i32, optname: i32, optval: u32) -> Std...
method setsockopt_bool (line 193) | fn setsockopt_bool(&self, level: i32, optname: i32, optval: bool) -> S...
method set_fail_connect_on_icmp_error (line 198) | fn set_fail_connect_on_icmp_error(&self, enabled: bool) -> IoResult<()> {
method set_non_blocking (line 204) | fn set_non_blocking(&self, is_non_blocking: bool) -> IoResult<()> {
method post_recv_from (line 212) | fn post_recv_from(&mut self) -> IoResult<()> {
method get_overlapped_result (line 240) | fn get_overlapped_result(&mut self) -> IoResult<()> {
method new_wsa_data (line 260) | const fn new_wsa_data() -> WSADATA {
method new_sockaddr_storage (line 266) | const fn new_sockaddr_storage() -> SOCKADDR_STORAGE {
method new_overlapped (line 272) | const fn new_overlapped() -> OVERLAPPED {
method new_icmp_error_info (line 278) | const fn new_icmp_error_info() -> ICMP_ERROR_INFO {
method drop (line 285) | fn drop(&mut self) {
method new_icmp_send_socket_ipv4 (line 295) | fn new_icmp_send_socket_ipv4(raw: bool) -> IoResult<Self> {
method new_icmp_send_socket_ipv6 (line 307) | fn new_icmp_send_socket_ipv6(raw: bool) -> IoResult<Self> {
method new_udp_send_socket_ipv4 (line 318) | fn new_udp_send_socket_ipv4(raw: bool) -> IoResult<Self> {
method new_udp_send_socket_ipv6 (line 330) | fn new_udp_send_socket_ipv6(raw: bool) -> IoResult<Self> {
method new_recv_socket_ipv4 (line 341) | fn new_recv_socket_ipv4(src_addr: Ipv4Addr, raw: bool) -> IoResult<Self> {
method new_recv_socket_ipv6 (line 355) | fn new_recv_socket_ipv6(src_addr: Ipv6Addr, raw: bool) -> IoResult<Self> {
method new_stream_socket_ipv4 (line 368) | fn new_stream_socket_ipv4() -> IoResult<Self> {
method new_stream_socket_ipv6 (line 376) | fn new_stream_socket_ipv6() -> IoResult<Self> {
method new_udp_dgram_socket_ipv4 (line 384) | fn new_udp_dgram_socket_ipv4() -> IoResult<Self> {
method new_udp_dgram_socket_ipv6 (line 389) | fn new_udp_dgram_socket_ipv6() -> IoResult<Self> {
method bind (line 394) | fn bind(&mut self, addr: SocketAddr) -> IoResult<()> {
method set_tos (line 410) | fn set_tos(&mut self, tos: u32) -> IoResult<()> {
method set_tclass_v6 (line 416) | fn set_tclass_v6(&mut self, tclass: u32) -> IoResult<()> {
method set_ttl (line 424) | fn set_ttl(&mut self, ttl: u32) -> IoResult<()> {
method set_reuse_port (line 431) | fn set_reuse_port(&mut self, is_reuse_port: bool) -> IoResult<()> {
method set_header_included (line 440) | fn set_header_included(&mut self, is_header_included: bool) -> IoResult<...
method set_unicast_hops_v6 (line 447) | fn set_unicast_hops_v6(&mut self, max_hops: u8) -> IoResult<()> {
method connect (line 454) | fn connect(&mut self, addr: SocketAddr) -> IoResult<()> {
method send_to (line 474) | fn send_to(&mut self, buf: &[u8], addr: SocketAddr) -> IoResult<()> {
method is_readable (line 483) | fn is_readable(&mut self, timeout: Duration) -> IoResult<bool> {
method is_writable (line 498) | fn is_writable(&mut self) -> IoResult<bool> {
method recv_from (line 513) | fn recv_from(&mut self, buf: &mut [u8]) -> IoResult<(usize, Option<Socke...
method read (line 526) | fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
method shutdown (line 535) | fn shutdown(&mut self) -> IoResult<()> {
method peer_addr (line 542) | fn peer_addr(&mut self) -> IoResult<Option<SocketAddr>> {
method take_error (line 551) | fn take_error(&mut self) -> IoResult<Option<SocketError>> {
method icmp_error_info (line 566) | fn icmp_error_info(&mut self) -> IoResult<IpAddr> {
method from (line 594) | fn from(value: &StdIoError) -> Self {
method from (line 613) | fn from(value: ErrorKind) -> Self {
function routing_interface_query (line 628) | fn routing_interface_query(target: IpAddr) -> Result<IpAddr> {
function sockaddrptr_to_ipaddr (line 661) | fn sockaddrptr_to_ipaddr(sockaddr: *mut SOCKADDR_STORAGE) -> StdIoResult...
function sockaddr_to_socketaddr (line 673) | fn sockaddr_to_socketaddr(sockaddr: &SOCKADDR_STORAGE) -> StdIoResult<So...
function socketaddr_to_sockaddr (line 713) | fn socketaddr_to_sockaddr(socketaddr: SocketAddr) -> (SOCKADDR_STORAGE, ...
function lookup_interface_addr (line 755) | fn lookup_interface_addr(adapters: &Adapters, name: &str) -> Result<IpAd...
type Adapters (line 784) | pub struct Adapters {
method ipv4 (line 790) | pub fn ipv4() -> Result<Self> {
method ipv6 (line 795) | pub fn ipv6() -> Result<Self> {
method iter (line 800) | pub fn iter(&self) -> AdaptersIter<'_> {
constant MAX_ATTEMPTS (line 805) | const MAX_ATTEMPTS: usize = 3;
constant INITIAL_BUFFER_SIZE (line 808) | const INITIAL_BUFFER_SIZE: u32 = 15000;
constant ADDRESS_FLAGS (line 811) | const ADDRESS_FLAGS: GET_ADAPTERS_ADDRESSES_FLAGS = IpHelper::GAA_FLAG...
method retrieve_addresses (line 815) | fn retrieve_addresses(family: ADDRESS_FAMILY) -> Result<Self> {
type AdapterAddress (line 847) | pub struct AdapterAddress {
type AdaptersIter (line 855) | pub struct AdaptersIter<'a> {
function new (line 862) | pub fn new(data: &'a Adapters) -> Self {
type Item (line 873) | type Item = AdapterAddress;
method next (line 875) | fn next(&mut self) -> Option<Self::Item> {
FILE: crates/trippy-core/src/net/socket.rs
type Socket (line 6) | pub trait Socket
method new_icmp_send_socket_ipv4 (line 11) | fn new_icmp_send_socket_ipv4(raw: bool) -> Result<Self>;
method new_icmp_send_socket_ipv6 (line 13) | fn new_icmp_send_socket_ipv6(raw: bool) -> Result<Self>;
method new_udp_send_socket_ipv4 (line 15) | fn new_udp_send_socket_ipv4(raw: bool) -> Result<Self>;
method new_udp_send_socket_ipv6 (line 17) | fn new_udp_send_socket_ipv6(raw: bool) -> Result<Self>;
method new_recv_socket_ipv4 (line 19) | fn new_recv_socket_ipv4(addr: Ipv4Addr, raw: bool) -> Result<Self>;
method new_recv_socket_ipv6 (line 21) | fn new_recv_socket_ipv6(addr: Ipv6Addr, raw: bool) -> Result<Self>;
method new_stream_socket_ipv4 (line 23) | fn new_stream_socket_ipv4() -> Result<Self>;
method new_stream_socket_ipv6 (line 25) | fn new_stream_socket_ipv6() -> Result<Self>;
method new_udp_dgram_socket_ipv4 (line 27) | fn new_udp_dgram_socket_ipv4() -> Result<Self>;
method new_udp_dgram_socket_ipv6 (line 29) | fn new_udp_dgram_socket_ipv6() -> Result<Self>;
method bind (line 30) | fn bind(&mut self, address: SocketAddr) -> Result<()>;
method set_tos (line 31) | fn set_tos(&mut self, tos: u32) -> Result<()>;
method set_tclass_v6 (line 32) | fn set_tclass_v6(&mut self, tclass: u32) -> Result<()>;
method set_ttl (line 33) | fn set_ttl(&mut self, ttl: u32) -> Result<()>;
method set_reuse_port (line 34) | fn set_reuse_port(&mut self, reuse: bool) -> Result<()>;
method set_header_included (line 35) | fn set_header_included(&mut self, included: bool) -> Result<()>;
method set_unicast_hops_v6 (line 36) | fn set_unicast_hops_v6(&mut self, hops: u8) -> Result<()>;
method connect (line 37) | fn connect(&mut self, address: SocketAddr) -> Result<()>;
method send_to (line 38) | fn send_to(&mut self, buf: &[u8], addr: SocketAddr) -> Result<()>;
method is_readable (line 40) | fn is_readable(&mut self, timeout: Duration) -> Result<bool>;
method is_writable (line 42) | fn is_writable(&mut self) -> Result<bool>;
method recv_from (line 43) | fn recv_from(&mut self, buf: &mut [u8]) -> Result<(usize, Option<Socke...
method read (line 44) | fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
method shutdown (line 45) | fn shutdown(&mut self) -> Result<()>;
method peer_addr (line 46) | fn peer_addr(&mut self) -> Result<Option<SocketAddr>>;
method take_error (line 47) | fn take_error(&mut self) -> Result<Option<SocketError>>;
method icmp_error_info (line 48) | fn icmp_error_info(&mut self) -> Result<IpAddr>;
type SocketError (line 53) | pub enum SocketError {
FILE: crates/trippy-core/src/net/source.rs
constant DISCOVERY_PORT (line 10) | const DISCOVERY_PORT: Port = Port(80);
type SourceAddr (line 13) | pub struct SourceAddr;
method discover (line 17) | pub fn discover<S: Socket, P: Platform>(
method validate (line 30) | pub fn validate<S: Socket>(source_addr: IpAddr) -> Result<IpAddr> {
function test_discover_local_addr_default_port (line 56) | fn test_discover_local_addr_default_port() {
function test_discover_local_addr_fixed_dest_port (line 78) | fn test_discover_local_addr_fixed_dest_port() {
function test_discover_local_addr_fixed_both_port (line 100) | fn test_discover_local_addr_fixed_both_port() {
function test_discover_lookup_interface (line 122) | fn test_discover_lookup_interface() {
function test_validate_ipv4 (line 147) | fn test_validate_ipv4() {
function test_validate_ipv6 (line 169) | fn test_validate_ipv6() {
function test_validate_invalid (line 191) | fn test_validate_invalid() {
FILE: crates/trippy-core/src/probe.rs
type ProbeStatus (line 18) | pub enum ProbeStatus {
method try_into_awaited (line 450) | pub fn try_into_awaited(self) -> Option<Probe> {
method try_into_complete (line 459) | pub fn try_into_complete(self) -> Option<ProbeComplete> {
type Probe (line 47) | pub struct Probe {
method new (line 70) | pub(crate) const fn new(
method complete (line 95) | pub(crate) const fn complete(
method failed (line 125) | pub(crate) const fn failed(self) -> ProbeFailed {
type ProbeComplete (line 148) | pub struct ProbeComplete {
type ProbeFailed (line 184) | pub struct ProbeFailed {
type IcmpPacketType (line 203) | pub enum IcmpPacketType {
type IcmpPacketCode (line 216) | pub struct IcmpPacketCode(pub u8);
type Response (line 220) | pub enum Response {
method data (line 230) | pub const fn data(&self) -> &ResponseData {
type Extensions (line 243) | pub struct Extensions {
type Extension (line 249) | pub enum Extension {
method default (line 255) | fn default() -> Self {
type MplsLabelStack (line 262) | pub struct MplsLabelStack {
type MplsLabelStackMember (line 268) | pub struct MplsLabelStackMember {
type UnknownExtension (line 277) | pub struct UnknownExtension {
type ResponseData (line 285) | pub struct ResponseData {
method new (line 295) | pub const fn new(recv: SystemTime, addr: IpAddr, proto_resp: ProtocolR...
type ProtocolResponse (line 315) | pub enum ProtocolResponse {
type IcmpProtocolResponse (line 323) | pub struct IcmpProtocolResponse {
method new (line 333) | pub const fn new(identifier: u16, sequence: u16, tos: Option<TypeOfSer...
type UdpProtocolResponse (line 344) | pub struct UdpProtocolResponse {
method new (line 387) | pub const fn new(
type TcpProtocolResponse (line 414) | pub struct TcpProtocolResponse {
method new (line 432) | pub const fn new(
FILE: crates/trippy-core/src/state.rs
type State (line 16) | pub struct State {
method new (line 32) | pub fn new(state_config: StateConfig) -> Self {
method default_flow_id (line 48) | pub const fn default_flow_id() -> FlowId {
method hops (line 54) | pub fn hops(&self) -> &[Hop] {
method hops_for_flow (line 60) | pub fn hops_for_flow(&self, flow_id: FlowId) -> &[Hop] {
method is_target (line 71) | pub fn is_target(&self, hop: &Hop, flow_id: FlowId) -> bool {
method is_in_round (line 77) | pub fn is_in_round(&self, hop: &Hop, flow_id: FlowId) -> bool {
method target_hop (line 83) | pub fn target_hop(&self, flow_id: FlowId) -> &Hop {
method round (line 89) | pub fn round(&self, flow_id: FlowId) -> Option<usize> {
method round_count (line 95) | pub fn round_count(&self, flow_id: FlowId) -> usize {
method round_flow_id (line 101) | pub const fn round_flow_id(&self) -> FlowId {
method flows (line 107) | pub fn flows(&self) -> &[(Flow, FlowId)] {
method error (line 113) | pub fn error(&self) -> Option<&str> {
method set_error (line 117) | pub fn set_error(&mut self, error: Option<String>) {
method max_samples (line 123) | pub const fn max_samples(&self) -> usize {
method max_flows (line 129) | pub const fn max_flows(&self) -> usize {
method update_from_round (line 135) | pub fn update_from_round(&mut self, round: &Round<'_>) {
method update_trace_flow (line 156) | fn update_trace_flow(&mut self, flow_id: FlowId, round: &Round<'_>) {
type Hop (line 167) | pub struct Hop {
method ttl (line 221) | pub const fn ttl(&self) -> u8 {
method addrs (line 226) | pub fn addrs(&self) -> impl Iterator<Item = &IpAddr> {
method addrs_with_counts (line 230) | pub fn addrs_with_counts(&self) -> impl Iterator<Item = (&IpAddr, &usi...
method addr_count (line 236) | pub fn addr_count(&self) -> usize {
method total_sent (line 242) | pub const fn total_sent(&self) -> usize {
method total_recv (line 248) | pub const fn total_recv(&self) -> usize {
method total_forward_loss (line 254) | pub const fn total_forward_loss(&self) -> usize {
method total_backward_loss (line 260) | pub const fn total_backward_loss(&self) -> usize {
method total_failed (line 266) | pub const fn total_failed(&self) -> usize {
method loss_pct (line 272) | pub fn loss_pct(&self) -> f64 {
method forward_loss_pct (line 283) | pub fn forward_loss_pct(&self) -> f64 {
method backward_loss_pct (line 294) | pub fn backward_loss_pct(&self) -> f64 {
method last_ms (line 305) | pub fn last_ms(&self) -> Option<f64> {
method best_ms (line 311) | pub fn best_ms(&self) -> Option<f64> {
method worst_ms (line 317) | pub fn worst_ms(&self) -> Option<f64> {
method avg_ms (line 323) | pub fn avg_ms(&self) -> f64 {
method stddev_ms (line 333) | pub fn stddev_ms(&self) -> f64 {
method jitter_ms (line 343) | pub fn jitter_ms(&self) -> Option<f64> {
method jmax_ms (line 349) | pub fn jmax_ms(&self) -> Option<f64> {
method javg_ms (line 355) | pub const fn javg_ms(&self) -> f64 {
method jinta (line 361) | pub const fn jinta(&self) -> f64 {
method last_src_port (line 367) | pub const fn last_src_port(&self) -> u16 {
method last_dest_port (line 373) | pub const fn last_dest_port(&self) -> u16 {
method last_sequence (line 379) | pub const fn last_sequence(&self) -> u16 {
method last_icmp_packet_type (line 385) | pub const fn last_icmp_packet_type(&self) -> Option<IcmpPacketType> {
method last_nat_status (line 391) | pub const fn last_nat_status(&self) -> NatStatus {
method tos (line 397) | pub fn tos(&self) -> Option<TypeOfService> {
method dscp (line 403) | pub fn dscp(&self) -> Option<Dscp> {
method ecn (line 409) | pub fn ecn(&self) -> Option<Ecn> {
method samples (line 415) | pub fn samples(&self) -> &[Duration] {
method extensions (line 420) | pub const fn extensions(&self) -> Option<&Extensions> {
method default (line 426) | fn default() -> Self {
type NatStatus (line 459) | pub enum NatStatus {
type FlowState (line 470) | struct FlowState {
method new (line 488) | fn new(max_samples: usize) -> Self {
method hops (line 500) | fn hops(&self) -> &[Hop] {
method is_target (line 510) | const fn is_target(&self, hop: &Hop) -> bool {
method is_in_round (line 514) | const fn is_in_round(&self, hop: &Hop) -> bool {
method target_hop (line 518) | fn target_hop(&self) -> &Hop {
method round (line 526) | const fn round(&self) -> Option<usize> {
method round_count (line 530) | const fn round_count(&self) -> usize {
method update_from_round (line 534) | fn update_from_round(&mut self, round: &Round<'_>) {
method update_round (line 538) | fn update_round(&mut self, round: RoundId) {
method update_lowest_ttl (line 545) | fn update_lowest_ttl(&mut self, ttl: TimeToLive) {
type StateUpdater (line 562) | pub(super) struct StateUpdater<'a> {
function new (line 573) | pub(super) fn new(state: &'a mut FlowState, round: &'a Round<'_>) -> Self {
function apply (line 583) | pub(super) fn apply(&mut self) {
function update_for_probe (line 594) | fn update_for_probe(&mut self, probe: &ProbeStatus) {
function is_forward_loss (line 693) | fn is_forward_loss(probes: &[ProbeStatus], awaited_ttl: TimeToLive) -> b...
function nat_status (line 715) | const fn nat_status(
function test_is_forward_loss (line 768) | fn test_is_forward_loss(expected: bool, probes: &[(char, u8)], awaited_t...
function test_nat (line 827) | const fn test_nat(expected: u16, actual: u16, prev: Option<u16>) -> (Nat...
type Scenario (line 853) | struct Scenario {
type RoundData (line 865) | struct RoundData {
type ProbeData (line 874) | struct ProbeData(ProbeStatus);
type Error (line 877) | type Error = anyhow::Error;
method try_from (line 879) | fn try_from(value: String) -> Result<Self, Self::Error> {
type ProbeRound (line 944) | struct ProbeRound(ProbeData, RoundId);
method from (line 947) | fn from(value: ProbeRound) -> Self {
type Expected (line 963) | struct Expected {
type HopData (line 971) | struct HopData {
type NatStatusWrapper (line 998) | struct NatStatusWrapper(NatStatus);
type Error (line 1001) | type Error = anyhow::Error;
method try_from (line 1003) | fn try_from(value: String) -> Result<Self, Self::Error> {
function test_scenario (line 1029) | fn test_scenario(scenario: Scenario) {
function assert_eq_opt (line 1104) | fn assert_eq_opt<T: Eq + Debug>(actual: Option<T>, expected: Option<T>) {
function assert_eq_opt_f64 (line 1108) | fn assert_eq_opt_f64(actual: Option<&f64>, expected: Option<&f64>) {
function assert_eq_vec_f64 (line 1112) | fn assert_eq_vec_f64(actual: Option<&Vec<f64>>, expected: Option<&Vec<f6...
function assert_eq_inner (line 1123) | fn assert_eq_inner<T: Debug>(
FILE: crates/trippy-core/src/strategy.rs
type Round (line 19) | pub struct Round<'a> {
function new (line 30) | pub const fn new(
type CompletionReason (line 45) | pub enum CompletionReason {
type Strategy (line 54) | pub struct Strategy<F> {
function new (line 61) | pub fn new(config: &StrategyConfig, publish: F) -> Self {
function run (line 71) | pub fn run<N: Network>(self, mut network: N) -> Result<()> {
function send_request (line 92) | fn send_request<N: Network>(&self, network: &mut N, st: &mut TracerState...
function do_send (line 135) | fn do_send<N: Network>(network: &mut N, st: &mut TracerState, probe: Pro...
function recv_response (line 165) | fn recv_response<N: Network>(&self, network: &mut N, st: &mut TracerStat...
function update_round (line 187) | fn update_round(&self, st: &mut TracerState) {
function publish_trace (line 205) | fn publish_trace(&self, state: &TracerState) {
function check_trace_id (line 230) | fn check_trace_id(&self, trace_id: TraceId) -> bool {
function validate (line 247) | fn validate(&self, resp: &ResponseData) -> bool {
type StrategyResponse (line 295) | struct StrategyResponse {
method from (line 309) | fn from((resp, config): (Response, &StrategyConfig)) -> Self {
type ProtocolStrategyResponse (line 379) | struct ProtocolStrategyResponse {
method from (line 388) | fn from((proto_resp, config): (ProtocolResponse, &StrategyConfig)) -> ...
function test_time_exceeded_target_response (line 474) | fn test_time_exceeded_target_response() {
function test_time_exceeded_not_target_response (line 495) | fn test_time_exceeded_not_target_response() {
function test_destination_unreachable_target_response (line 516) | fn test_destination_unreachable_target_response() {
function test_destination_unreachable_not_target_response (line 538) | fn test_destination_unreachable_not_target_response() {
function test_echo_reply_response (line 557) | fn test_echo_reply_response() {
function test_tcp_reply_response (line 575) | fn test_tcp_reply_response() {
function test_tcp_refused_response (line 590) | fn test_tcp_refused_response() {
function test_icmp_response (line 605) | fn test_icmp_response() {
function test_udp_classic_fixed_src_response (line 618) | fn test_udp_classic_fixed_src_response() {
function test_udp_classic_fixed_dest_response (line 641) | fn test_udp_classic_fixed_dest_response() {
function test_udp_paris_response (line 664) | fn test_udp_paris_response() {
function test_udp_dublin_ipv4_response (line 688) | fn test_udp_dublin_ipv4_response() {
function test_udp_dublin_ipv6_response (line 712) | fn test_udp_dublin_ipv6_response() {
function test_tcp_fixed_dest_response (line 737) | fn test_tcp_fixed_dest_response() {
function test_tcp_fixed_src_response (line 760) | fn test_tcp_fixed_src_response() {
function test_tcp_dest_unreachable_and_refused (line 791) | fn test_tcp_dest_unreachable_and_refused() -> anyhow::Result<()> {
function response_data (line 851) | const fn response_data(now: SystemTime) -> ResponseData {
constant BUFFER_SIZE (line 883) | const BUFFER_SIZE: u16 = MAX_SEQUENCE_PER_ROUND;
constant MAX_SEQUENCE (line 902) | const MAX_SEQUENCE: Sequence = Sequence(u16::MAX - BUFFER_SIZE);
type TracerState (line 906) | pub struct TracerState {
method new (line 935) | pub fn new(config: StrategyConfig) -> Self {
method probes (line 952) | pub fn probes(&self) -> &[ProbeStatus] {
method probe_at (line 958) | pub fn probe_at(&self, sequence: Sequence) -> ProbeStatus {
method ttl (line 962) | pub const fn ttl(&self) -> TimeToLive {
method round_start (line 966) | pub const fn round_start(&self) -> SystemTime {
method target_found (line 970) | pub const fn target_found(&self) -> bool {
method max_received_ttl (line 974) | pub const fn max_received_ttl(&self) -> Option<TimeToLive> {
method target_ttl (line 978) | pub const fn target_ttl(&self) -> Option<TimeToLive> {
method received_time (line 982) | pub const fn received_time(&self) -> Option<SystemTime> {
method in_round (line 987) | pub fn in_round(&self, sequence: Sequence) -> bool {
method round_has_capacity (line 992) | pub fn round_has_capacity(&self) -> bool {
method finished (line 998) | pub const fn finished(&self, max_rounds: Option<MaxRounds>) -> bool {
method next_probe (line 1010) | pub fn next_probe(&mut self, sent: SystemTime) -> Probe {
method reissue_probe (line 1041) | pub fn reissue_probe(&mut self, sent: SystemTime) -> Probe {
method fail_probe (line 1063) | pub fn fail_probe(&mut self) {
method probe_data (line 1078) | fn probe_data(&self) -> (Port, Port, TraceId, Flags) {
method probe_icmp_data (line 1087) | const fn probe_icmp_data(&self) -> (Port, Port, TraceId, Flags) {
method probe_udp_data (line 1097) | fn probe_udp_data(&self) -> (Port, Port, TraceId, Flags) {
method probe_tcp_data (line 1170) | fn probe_tcp_data(&self) -> (Port, Port, TraceId, Flags) {
method complete_probe (line 1193) | pub fn complete_probe(&mut self, resp: StrategyResponse) {
method advance_round (line 1260) | pub fn advance_round(&mut self, first_ttl: TimeToLive) {
method max_sequence (line 1283) | fn max_sequence(&self) -> Sequence {
function test_state (line 1305) | fn test_state() {
function test_sequence_wrap1 (line 1480) | fn test_sequence_wrap1() {
function test_sequence_wrap2 (line 1542) | fn test_sequence_wrap2() {
function test_sequence_wrap3 (line 1558) | fn test_sequence_wrap3() {
function test_sequence_wrap_with_skip (line 1572) | fn test_sequence_wrap_with_skip() {
function test_in_round (line 1589) | fn test_in_round() {
function test_in_delayed_probe_not_in_round (line 1598) | fn test_in_delayed_probe_not_in_round() {
function cfg (line 1607) | fn cfg(initial_sequence: Sequence) -> StrategyConfig {
function exceeds (line 1628) | fn exceeds(start: Option<SystemTime>, end: SystemTime, dur: Duration) ->...
FILE: crates/trippy-core/src/tracer.rs
type Tracer (line 20) | pub struct Tracer {
method new (line 30) | pub(crate) fn new(
method run (line 126) | pub fn run(&self) -> Result<()> {
method run_with (line 165) | pub fn run_with<F: Fn(&Round<'_>)>(&self, func: F) -> Result<()> {
method spawn (line 207) | pub fn spawn(self) -> Result<(Self, JoinHandle<Result<()>>)> {
method spawn_with (line 255) | pub fn spawn_with<F: Fn(&Round<'_>) + Send + 'static>(
method snapshot (line 269) | pub fn snapshot(&self) -> State {
method clear (line 274) | pub fn clear(&self) {
method max_flows (line 280) | pub fn max_flows(&self) -> usize {
method max_samples (line 286) | pub fn max_samples(&self) -> usize {
method privilege_mode (line 292) | pub fn privilege_mode(&self) -> PrivilegeMode {
method protocol (line 298) | pub fn protocol(&self) -> Protocol {
method interface (line 304) | pub fn interface(&self) -> Option<&str> {
method source_addr (line 310) | pub fn source_addr(&self) -> Option<IpAddr> {
method target_addr (line 316) | pub fn target_addr(&self) -> IpAddr {
method packet_size (line 322) | pub fn packet_size(&self) -> PacketSize {
method payload_pattern (line 328) | pub fn payload_pattern(&self) -> PayloadPattern {
method initial_sequence (line 334) | pub fn initial_sequence(&self) -> Sequence {
method tos (line 340) | pub fn tos(&self) -> TypeOfService {
method icmp_extension_parse_mode (line 346) | pub fn icmp_extension_parse_mode(&self) -> IcmpExtensionParseMode {
method read_timeout (line 352) | pub fn read_timeout(&self) -> Duration {
method tcp_connect_timeout (line 358) | pub fn tcp_connect_timeout(&self) -> Duration {
method trace_identifier (line 364) | pub fn trace_identifier(&self) -> TraceId {
method max_rounds (line 370) | pub fn max_rounds(&self) -> Option<MaxRounds> {
method first_ttl (line 376) | pub fn first_ttl(&self) -> TimeToLive {
method max_ttl (line 382) | pub fn max_ttl(&self) -> TimeToLive {
method grace_duration (line 388) | pub fn grace_duration(&self) -> Duration {
method max_inflight (line 394) | pub fn max_inflight(&self) -> MaxInflight {
method multipath_strategy (line 400) | pub fn multipath_strategy(&self) -> MultipathStrategy {
method port_direction (line 406) | pub fn port_direction(&self) -> PortDirection {
method min_round_duration (line 412) | pub fn min_round_duration(&self) -> Duration {
method max_round_duration (line 418) | pub fn max_round_duration(&self) -> Duration {
type TracerInner (line 441) | pub(super) struct TracerInner {
method new (line 473) | pub(super) fn new(
method run (line 532) | pub(super) fn run(&self) -> Result<()> {
method run_with (line 538) | pub(super) fn run_with<F: Fn(&Round<'_>)>(&self, func: F) -> Result<()> {
method snapshot (line 543) | pub(super) fn snapshot(&self) -> State {
method clear (line 547) | pub(super) fn clear(&self) {
method max_flows (line 552) | pub(super) const fn max_flows(&self) -> usize {
method max_samples (line 556) | pub(super) const fn max_samples(&self) -> usize {
method privilege_mode (line 560) | pub(super) const fn privilege_mode(&self) -> PrivilegeMode {
method protocol (line 564) | pub(super) const fn protocol(&self) -> Protocol {
method interface (line 568) | pub(super) fn interface(&self) -> Option<&str> {
method source_addr (line 572) | pub(super) fn source_addr(&self) -> Option<IpAddr> {
method target_addr (line 576) | pub(super) const fn target_addr(&self) -> IpAddr {
method packet_size (line 580) | pub(super) const fn packet_size(&self) -> PacketSize {
method payload_pattern (line 584) | pub(super) const fn payload_pattern(&self) -> PayloadPattern {
method initial_sequence (line 588) | pub(super) const fn initial_sequence(&self) -> Sequence {
method tos (line 592) | pub(super) const fn tos(&self) -> TypeOfService {
method icmp_extension_parse_mode (line 596) | pub(super) const fn icmp_extension_parse_mode(&self) -> IcmpExtensionP...
method read_timeout (line 600) | pub(super) const fn read_timeout(&self) -> Duration {
method tcp_connect_timeout (line 604) | pub(super) const fn tcp_connect_timeout(&self) -> Duration {
method trace_identifier (line 608) | pub(super) const fn trace_identifier(&self) -> TraceId {
method max_rounds (line 612) | pub(super) const fn max_rounds(&self) -> Option<MaxRounds> {
method first_ttl (line 616) | pub(super) const fn first_ttl(&self) -> TimeToLive {
method max_ttl (line 620) | pub(super) const fn max_ttl(&self) -> TimeToLive {
method grace_duration (line 624) | pub(super) const fn grace_duration(&self) -> Duration {
method max_inflight (line 628) | pub(super) const fn max_inflight(&self) -> MaxInflight {
method multipath_strategy (line 632) | pub(super) const fn multipath_strategy(&self) -> MultipathStrategy {
method port_direction (line 636) | pub(super) const fn port_direction(&self) -> PortDirection {
method min_round_duration (line 640) | pub(super) const fn min_round_duration(&self) -> Duration {
method max_round_duration (line 644) | pub(super) const fn max_round_duration(&self) -> Duration {
method run_internal (line 649) | fn run_internal<F: Fn(&Round<'_>)>(&self, func: F) -> Result<()> {
method handler (line 677) | fn handler(&self, round: &Round<'_>) {
method handle_error (line 681) | fn handle_error(&self, err: Error) -> Error {
method make_state_config (line 686) | const fn make_state_config(max_flows: usize, max_samples: usize) -> St...
method make_channel_config (line 693) | const fn make_channel_config(&self, source_addr: IpAddr) -> ChannelCon...
method make_strategy_config (line 709) | const fn make_strategy_config(&self) -> StrategyConfig {
FILE: crates/trippy-core/src/types.rs
type RoundId (line 7) | pub struct RoundId(pub usize);
type MaxRounds (line 11) | pub struct MaxRounds(pub NonZeroUsize);
type TimeToLive (line 15) | pub struct TimeToLive(pub u8);
type Sequence (line 19) | pub struct Sequence(pub u16);
type TraceId (line 23) | pub struct TraceId(pub u16);
type MaxInflight (line 27) | pub struct MaxInflight(pub u8);
type PacketSize (line 31) | pub struct PacketSize(pub u16);
type PayloadPattern (line 35) | pub struct PayloadPattern(pub u8);
type TypeOfService (line 39) | pub struct TypeOfService(pub u8);
method dscp (line 151) | pub fn dscp(&self) -> Dscp {
method ecn (line 155) | pub fn ecn(&self) -> Ecn {
method split (line 158) | fn split(self) -> (Dscp, Ecn) {
type Port (line 43) | pub struct Port(pub u16);
type Checksum (line 47) | pub struct Checksum(pub u16);
function from (line 61) | fn from(sequence: Sequence) -> Self {
type Ecn (line 72) | pub enum Ecn {
type Dscp (line 94) | pub enum Dscp {
function test_dscp_ecn (line 206) | fn test_dscp_ecn(tos: TypeOfService, dscp: Dscp, ecn: Ecn) {
FILE: crates/trippy-core/tests/sim/network.rs
constant READ_TIMEOUT (line 19) | const READ_TIMEOUT: Duration = Duration::from_millis(10);
function run (line 21) | pub async fn run(
function read_with_timeout (line 104) | async fn read_with_timeout(buf: &mut [u8], tun: Arc<Mutex<TunDevice>>) -...
function write_packet (line 110) | async fn write_packet(
FILE: crates/trippy-core/tests/sim/network/ipv4.rs
function process (line 16) | pub fn process(sim: &Simulation, packet_buf: &[u8]) -> anyhow::Result<Op...
function make_time_exceeded (line 163) | fn make_time_exceeded<'a>(
function make_echo_reply (line 175) | fn make_echo_reply(
function make_destination_unreachable (line 189) | fn make_destination_unreachable<'a>(
function make_tcp_syn_ack (line 201) | fn make_tcp_syn_ack<'a>(
function make_ip (line 222) | fn make_ip<'a>(
FILE: crates/trippy-core/tests/sim/network/ipv6.rs
function process (line 16) | pub fn process(sim: &Simulation, packet_buf: &[u8]) -> anyhow::Result<Op...
function make_time_exceeded (line 172) | fn make_time_exceeded<'a>(
function make_echo_reply (line 186) | fn make_echo_reply(
function make_destination_unreachable (line 202) | fn make_destination_unreachable<'a>(
function make_tcp_syn_ack (line 216) | fn make_tcp_syn_ack<'a>(
function make_ip (line 237) | fn make_ip<'a>(
FILE: crates/trippy-core/tests/sim/simulation.rs
type Simulation (line 8) | pub struct Simulation {
method latest_ttl (line 32) | pub fn latest_ttl(&self) -> u8 {
type Hop (line 44) | pub struct Hop {
type Response (line 54) | pub enum Response {
type SingleHost (line 64) | pub struct SingleHost {
type PrivilegeMode (line 72) | pub enum PrivilegeMode {
function from (line 79) | fn from(value: PrivilegeMode) -> Self {
type Protocol (line 88) | pub enum Protocol {
function from (line 95) | fn from(value: Protocol) -> Self {
type PortDirection (line 106) | pub enum PortDirection {
type FixedBoth (line 116) | pub struct FixedBoth {
function from (line 122) | fn from(value: PortDirection) -> Self {
type MultipathStrategy (line 135) | pub enum MultipathStrategy {
function from (line 143) | fn from(value: MultipathStrategy) -> Self {
FILE: crates/trippy-core/tests/sim/tests.rs
constant MAX_ATTEMPTS (line 12) | const MAX_ATTEMPTS: usize = 5;
function runtime (line 16) | pub fn runtime() -> &'static Arc<Mutex<Runtime>> {
function test_simulation (line 60) | fn test_simulation(simulation: Simulation) -> anyhow::Result<()> {
function test_simulation_macos (line 70) | fn test_simulation_macos(simulation: Simulation) -> anyhow::Result<()> {
function run_simulation_with_retry (line 74) | fn run_simulation_with_retry(simulation: Simulation) -> anyhow::Result<(...
function run_simulation (line 95) | async fn run_simulation(sim: Arc<Simulation>) -> anyhow::Result<()> {
FILE: crates/trippy-core/tests/sim/tracer.rs
constant CLEANUP_DELAY (line 20) | const CLEANUP_DELAY: Duration = Duration::from_millis(1000);
type Tracer (line 42) | pub struct Tracer {
method new (line 48) | pub const fn new(sim: Arc<Simulation>, token: CancellationToken) -> Se...
method trace (line 52) | pub fn trace(&self) -> anyhow::Result<()> {
method validate_round (line 104) | fn validate_round(&self, round: &Round<'_>, result: &RefCell<anyhow::R...
FILE: crates/trippy-core/tests/sim/tun_device.rs
function tun (line 8) | pub fn tun() -> &'static Arc<Mutex<TunDevice>> {
constant TUN_NETWORK_ADDR_V4 (line 21) | pub const TUN_NETWORK_ADDR_V4: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 1);
constant TUN_NETWORK_PREFIX_V4 (line 22) | const TUN_NETWORK_PREFIX_V4: u8 = 24;
constant TUN_NETWORK_ADDR_V6 (line 25) | pub const TUN_NETWORK_ADDR_V6: Ipv6Addr = Ipv6Addr::new(0xfd00, 0x0010, ...
constant TUN_NETWORK_PREFIX_V6 (line 26) | const TUN_NETWORK_PREFIX_V6: u8 = 64;
type TunDevice (line 29) | pub struct TunDevice {
method start (line 34) | pub fn start() -> anyhow::Result<Self> {
method read (line 44) | pub async fn read(&self, buf: &mut [u8]) -> std::io::Result<usize> {
method write (line 49) | pub async fn write(&self, buf: &[u8]) -> std::io::Result<usize> {
FILE: crates/trippy-dns/src/config.rs
type Builder (line 14) | pub struct Builder {
method new (line 24) | pub fn new() -> Self {
method resolve_method (line 35) | pub const fn resolve_method(self, resolve_method: ResolveMethod) -> Se...
method addr_family (line 44) | pub const fn addr_family(self, addr_family: IpAddrFamily) -> Self {
method timeout (line 53) | pub const fn timeout(self, timeout: Duration) -> Self {
method ttl (line 59) | pub const fn ttl(self, ttl: Duration) -> Self {
method build (line 65) | pub const fn build(self) -> Config {
method default (line 76) | fn default() -> Self {
type Config (line 83) | pub struct Config {
method new (line 97) | pub const fn new(
method default (line 113) | fn default() -> Self {
FILE: crates/trippy-dns/src/lazy_resolver.rs
type ResolveMethod (line 9) | pub enum ResolveMethod {
type IpAddrFamily (line 22) | pub enum IpAddrFamily {
method fmt (line 37) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type DnsResolver (line 50) | pub struct DnsResolver {
method start (line 56) | pub fn start(config: Config) -> std::io::Result<Self> {
method config (line 64) | pub fn config(&self) -> &Config {
method flush (line 69) | pub fn flush(&self) {
method start (line 162) | pub(super) fn start(config: Config) -> std::io::Result<Self> {
method config (line 212) | pub(super) const fn config(&self) -> &Config {
method lookup (line 216) | pub(super) fn lookup(&self, hostname: &str) -> Result<ResolvedIpAddrs> {
method reverse_lookup (line 256) | pub(super) fn reverse_lookup(
method lazy_reverse_lookup (line 269) | fn lazy_reverse_lookup(&self, addr: IpAddr, with_asinfo: bool) -> Cach...
method flush (line 343) | pub fn flush(&self) {
method lookup (line 75) | fn lookup(&self, hostname: impl AsRef<str>) -> Result<ResolvedIpAddrs> {
method reverse_lookup (line 78) | fn reverse_lookup(&self, addr: impl Into<IpAddr>) -> DnsEntry {
method reverse_lookup_with_asinfo (line 81) | fn reverse_lookup_with_asinfo(&self, addr: impl Into<IpAddr>) -> DnsEntry {
method lazy_reverse_lookup (line 84) | fn lazy_reverse_lookup(&self, addr: impl Into<IpAddr>) -> DnsEntry {
method lazy_reverse_lookup_with_asinfo (line 87) | fn lazy_reverse_lookup_with_asinfo(&self, addr: impl Into<IpAddr>) -> Dn...
constant RESOLVER_MAX_QUEUE_SIZE (line 113) | const RESOLVER_MAX_QUEUE_SIZE: usize = 100;
constant RESOLVER_QUEUE_TIMEOUT (line 117) | const RESOLVER_QUEUE_TIMEOUT: Duration = Duration::from_millis(10);
type Cache (line 120) | type Cache = Arc<RwLock<HashMap<IpAddr, CacheEntry>>>;
type CacheEntry (line 124) | struct CacheEntry {
method new (line 132) | const fn new(entry: DnsEntry, timestamp: SystemTime) -> Self {
method set_timestamp (line 136) | fn set_timestamp(&mut self, timestamp: SystemTime) {
type DnsProvider (line 142) | enum DnsProvider {
type DnsResolveRequest (line 148) | struct DnsResolveRequest {
type DnsResolver (line 154) | pub(super) struct DnsResolver {
method start (line 56) | pub fn start(config: Config) -> std::io::Result<Self> {
method config (line 64) | pub fn config(&self) -> &Config {
method flush (line 69) | pub fn flush(&self) {
method start (line 162) | pub(super) fn start(config: Config) -> std::io::Result<Self> {
method config (line 212) | pub(super) const fn config(&self) -> &Config {
method lookup (line 216) | pub(super) fn lookup(&self, hostname: &str) -> Result<ResolvedIpAddrs> {
method reverse_lookup (line 256) | pub(super) fn reverse_lookup(
method lazy_reverse_lookup (line 269) | fn lazy_reverse_lookup(&self, addr: IpAddr, with_asinfo: bool) -> Cach...
method flush (line 343) | pub fn flush(&self) {
function resolver_queue_processor (line 352) | fn resolver_queue_processor(
function reverse_lookup (line 363) | fn reverse_lookup(provider: &DnsProvider, addr: IpAddr, with_asinfo: boo...
function lookup_asinfo (line 416) | fn lookup_asinfo(resolver: &Arc<Resolver>, addr: IpAddr) -> Result<AsInf...
function query_asn_ipv4 (line 435) | fn query_asn_ipv4(resolver: &Arc<Resolver>, addr: Ipv4Addr) -> Result<St...
function query_asn_ipv6 (line 453) | fn query_asn_ipv6(resolver: &Arc<Resolver>, addr: Ipv6Addr) -> Result<St...
function query_asn_name (line 475) | fn query_asn_name(resolver: &Arc<Resolver>, asn: &str) -> Result<String> {
function parse_origin_query_txt (line 496) | fn parse_origin_query_txt(origin_query_txt: &str) -> Result<AsInfo> {
function parse_asn_query_txt (line 525) | fn parse_asn_query_txt(asn_query_txt: &str) -> Result<String> {
function resolve_error (line 534) | fn resolve_error(err: ResolveError) -> Error {
function proto_error (line 539) | fn proto_error(err: ProtoError) -> Error {
FILE: crates/trippy-dns/src/resolver.rs
type Resolver (line 6) | pub trait Resolver {
method lookup (line 8) | fn lookup(&self, hostname: impl AsRef<str>) -> Result<ResolvedIpAddrs>;
method reverse_lookup (line 14) | fn reverse_lookup(&self, addr: impl Into<IpAddr>) -> DnsEntry;
method reverse_lookup_with_asinfo (line 21) | fn reverse_lookup_with_asinfo(&self, addr: impl Into<IpAddr>) -> DnsEn...
method lazy_reverse_lookup (line 35) | fn lazy_reverse_lookup(&self, addr: impl Into<IpAddr>) -> DnsEntry;
method lazy_reverse_lookup_with_asinfo (line 41) | fn lazy_reverse_lookup_with_asinfo(&self, addr: impl Into<IpAddr>) -> ...
type Result (line 45) | pub type Result<T> = std::result::Result<T, Error>;
type Error (line 49) | pub enum Error {
type ResolvedIpAddrs (line 64) | pub struct ResolvedIpAddrs(pub(super) Vec<IpAddr>);
method iter (line 67) | pub fn iter(&self) -> impl Iterator<Item = &'_ IpAddr> {
type Item (line 73) | type Item = IpAddr;
type IntoIter (line 74) | type IntoIter = std::vec::IntoIter<Self::Item>;
method into_iter (line 76) | fn into_iter(self) -> Self::IntoIter {
type DnsEntry (line 83) | pub enum DnsEntry {
method hostnames (line 111) | pub fn hostnames(&self) -> ResolvedHostnames<'_> {
type ResolvedHostnames (line 98) | pub struct ResolvedHostnames<'a>(pub(super) std::slice::Iter<'a, String>);
type Item (line 101) | type Item = &'a str;
method next (line 103) | fn next(&mut self) -> Option<Self::Item> {
type Resolved (line 125) | pub enum Resolved {
type Unresolved (line 134) | pub enum Unresolved {
type AsInfo (line 143) | pub struct AsInfo {
method fmt (line 171) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_iterator_returns_each_hostname_once (line 196) | fn test_iterator_returns_each_hostname_once() {
FILE: crates/trippy-packet/src/buffer.rs
type Buffer (line 3) | pub enum Buffer<'a> {
function as_slice (line 10) | pub fn as_slice(&self) -> &[u8] {
function get_bytes (line 18) | pub fn get_bytes<const N: usize>(&self, offset: usize) -> [u8; N] {
function set_bytes (line 23) | pub fn set_bytes<const N: usize>(&mut self, offset: usize, bytes: [u8; N...
function read (line 28) | pub fn read(&self, offset: usize) -> u8 {
function write (line 36) | pub fn write(&mut self, offset: usize) -> &mut u8 {
function as_slice_mut (line 44) | pub fn as_slice_mut(&mut self) -> &mut [u8] {
function test_immutable_buffer (line 57) | fn test_immutable_buffer() {
function test_mutable_buffer (line 66) | fn test_mutable_buffer() {
function test_debug (line 81) | fn test_debug() {
function test_immutable_buffer_cannot_write (line 98) | fn test_immutable_buffer_cannot_write() {
function test_immutable_buffer_cannot_mut_slice (line 106) | fn test_immutable_buffer_cannot_mut_slice() {
FILE: crates/trippy-packet/src/checksum.rs
function ipv4_header_checksum (line 12) | pub fn ipv4_header_checksum(data: &[u8]) -> u16 {
function icmp_ipv4_checksum (line 18) | pub fn icmp_ipv4_checksum(data: &[u8]) -> u16 {
function icmp_ipv6_checksum (line 24) | pub fn icmp_ipv6_checksum(data: &[u8], src_addr: Ipv6Addr, dest_addr: Ip...
function udp_ipv4_checksum (line 30) | pub fn udp_ipv4_checksum(data: &[u8], src_addr: Ipv4Addr, dest_addr: Ipv...
function tcp_ipv4_checksum (line 36) | pub fn tcp_ipv4_checksum(data: &[u8], src_addr: Ipv4Addr, dest_addr: Ipv...
function udp_ipv6_checksum (line 42) | pub fn udp_ipv6_checksum(data: &[u8], src_addr: Ipv6Addr, dest_addr: Ipv...
function tcp_ipv6_checksum (line 48) | pub fn tcp_ipv6_checksum(data: &[u8], src_addr: Ipv6Addr, dest_addr: Ipv...
function checksum (line 52) | fn checksum(data: &[u8], ignore_word: usize) -> u16 {
function ipv4_checksum (line 60) | fn ipv4_checksum(
function ipv4_word_sum (line 76) | fn ipv4_word_sum(ip: Ipv4Addr) -> u32 {
function ipv6_checksum (line 83) | fn ipv6_checksum(
function ipv6_word_sum (line 99) | fn ipv6_word_sum(ip: Ipv6Addr) -> u32 {
function sum_be_words (line 103) | fn sum_be_words(data: &[u8], ignore_word: usize) -> u32 {
function finalize_checksum (line 124) | const fn finalize_checksum(mut sum: u32) -> u16 {
function test_empty_ipv4_checksum (line 138) | fn test_empty_ipv4_checksum() {
function test_empty_ipv6_checksum (line 148) | fn test_empty_ipv6_checksum() {
function test_odd_length (line 156) | fn test_odd_length() {
function test_icmp_ipv4_checksum (line 161) | fn test_icmp_ipv4_checksum() {
function test_icmp_ipv6_checksum (line 175) | fn test_icmp_ipv6_checksum() {
function test_udp_ipv4_checksum (line 186) | fn test_udp_ipv4_checksum() {
function test_udp_ipv6_checksum (line 200) | fn test_udp_ipv6_checksum() {
function test_tcp_ipv6_checksum (line 213) | fn test_tcp_ipv6_checksum() {
function test_ipv4_header_checksum (line 221) | fn test_ipv4_header_checksum() {
function test_tcp_ipv4_checksum (line 227) | fn test_tcp_ipv4_checksum() {
FILE: crates/trippy-packet/src/error.rs
type Result (line 4) | pub type Result<T> = std::result::Result<T, Error>;
type Error (line 8) | pub enum Error {
FILE: crates/trippy-packet/src/icmp_extension.rs
type ExtensionsPacket (line 11) | pub struct ExtensionsPacket<'a> {
function new (line 16) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 30) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 45) | pub const fn minimum_packet_size() -> usize {
function packet (line 50) | pub fn packet(&self) -> &[u8] {
function header (line 55) | pub fn header(&self) -> &[u8] {
function objects (line 61) | pub const fn objects(&self) -> ExtensionObjectIter<'_> {
type ExtensionObjectIter (line 66) | pub struct ExtensionObjectIter<'a> {
function new (line 73) | pub const fn new(buf: &'a Buffer<'_>) -> Self {
type Item (line 82) | type Item = &'a [u8];
method next (line 84) | fn next(&mut self) -> Option<Self::Item> {
function test_header (line 117) | fn test_header() {
function test_object_iterator (line 128) | fn test_object_iterator() {
function test_object_iterator_zero_length (line 147) | fn test_object_iterator_zero_length() {
function test_object_iterator_minimum_length (line 157) | fn test_object_iterator_minimum_length() {
function test_object_iterator_length_to_short (line 170) | fn test_object_iterator_length_to_short() {
function test_object_iterator_length_to_long (line 180) | fn test_object_iterator_length_to_long() {
constant VERSION_OFFSET (line 196) | const VERSION_OFFSET: usize = 0;
constant CHECKSUM_OFFSET (line 197) | const CHECKSUM_OFFSET: usize = 2;
type ExtensionHeaderPacket (line 204) | pub struct ExtensionHeaderPacket<'a> {
function new (line 209) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 223) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 238) | pub const fn minimum_packet_size() -> usize {
function get_version (line 243) | pub fn get_version(&self) -> u8 {
function get_checksum (line 248) | pub fn get_checksum(&self) -> u16 {
function set_version (line 252) | pub fn set_version(&mut self, val: u8) {
function set_checksum (line 257) | pub fn set_checksum(&mut self, val: u16) {
function packet (line 262) | pub fn packet(&self) -> &[u8] {
method fmt (line 268) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_version (line 281) | fn test_version() {
function test_checksum (line 296) | fn test_checksum() {
function test_extension_header_view (line 314) | fn test_extension_header_view() {
type ClassNum (line 333) | pub enum ClassNum {
method id (line 343) | pub const fn id(&self) -> u8 {
method from (line 355) | fn from(val: u8) -> Self {
type ClassSubType (line 368) | pub struct ClassSubType(pub u8);
method from (line 371) | fn from(val: u8) -> Self {
constant LENGTH_OFFSET (line 376) | const LENGTH_OFFSET: usize = 0;
constant CLASS_NUM_OFFSET (line 377) | const CLASS_NUM_OFFSET: usize = 2;
constant CLASS_SUBTYPE_OFFSET (line 378) | const CLASS_SUBTYPE_OFFSET: usize = 3;
type ExtensionObjectPacket (line 385) | pub struct ExtensionObjectPacket<'a> {
function new (line 390) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 404) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 419) | pub const fn minimum_packet_size() -> usize {
function set_length (line 423) | pub fn set_length(&mut self, val: u16) {
function set_class_num (line 427) | pub fn set_class_num(&mut self, val: ClassNum) {
function set_class_subtype (line 431) | pub fn set_class_subtype(&mut self, val: ClassSubType) {
function set_payload (line 435) | pub fn set_payload(&mut self, vals: &[u8]) {
function get_length (line 442) | pub fn get_length(&self) -> u16 {
function get_class_num (line 447) | pub fn get_class_num(&self) -> ClassNum {
function get_class_subtype (line 452) | pub fn get_class_subtype(&self) -> ClassSubType {
function packet (line 457) | pub fn packet(&self) -> &[u8] {
function payload (line 462) | pub fn payload(&self) -> &[u8] {
method fmt (line 468) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_length (line 483) | fn test_length() {
function test_class_num (line 498) | fn test_class_num() {
function test_class_subtype (line 528) | fn test_class_subtype() {
function test_extension_header_view (line 543) | fn test_extension_header_view() {
type MplsLabelStackPacket (line 567) | pub struct MplsLabelStackPacket<'a> {
function new (line 572) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 586) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 601) | pub const fn minimum_packet_size() -> usize {
function packet (line 606) | pub fn packet(&self) -> &[u8] {
function members (line 611) | pub const fn members(&self) -> MplsLabelStackIter<'_> {
type MplsLabelStackIter (line 616) | pub struct MplsLabelStackIter<'a> {
function new (line 624) | pub const fn new(buf: &'a Buffer<'_>) -> Self {
type Item (line 634) | type Item = &'a [u8];
method next (line 636) | fn next(&mut self) -> Option<Self::Item> {
function test_stack_member_iterator (line 657) | fn test_stack_member_iterator() {
constant LABEL_OFFSET (line 677) | const LABEL_OFFSET: usize = 0;
constant EXP_OFFSET (line 678) | const EXP_OFFSET: usize = 2;
constant BOS_OFFSET (line 679) | const BOS_OFFSET: usize = 2;
constant TTL_OFFSET (line 680) | const TTL_OFFSET: usize = 3;
type MplsLabelStackMemberPacket (line 687) | pub struct MplsLabelStackMemberPacket<'a> {
function new (line 692) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 706) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 721) | pub const fn minimum_packet_size() -> usize {
function get_label (line 726) | pub fn get_label(&self) -> u32 {
function get_exp (line 736) | pub fn get_exp(&self) -> u8 {
function get_bos (line 741) | pub fn get_bos(&self) -> u8 {
function get_ttl (line 746) | pub fn get_ttl(&self) -> u8 {
function set_label (line 750) | pub fn set_label(&mut self, val: u32) {
function set_exp (line 758) | pub fn set_exp(&mut self, exp: u8) {
function set_bos (line 762) | pub fn set_bos(&mut self, bos: u8) {
function set_ttl (line 766) | pub fn set_ttl(&mut self, ttl: u8) {
function packet (line 771) | pub fn packet(&self) -> &[u8] {
method fmt (line 777) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_label (line 792) | fn test_label() {
function test_exp (line 807) | fn test_exp() {
function test_bos (line 819) | fn test_bos() {
function test_ttl (line 831) | fn test_ttl() {
function test_combined (line 846) | fn test_combined() {
function test_view (line 870) | fn test_view() {
constant MIN_HEADER (line 883) | const MIN_HEADER: usize = ExtensionHeaderPacket::minimum_packet_size();
constant ICMP_ORIG_DATAGRAM_MIN_LENGTH (line 890) | const ICMP_ORIG_DATAGRAM_MIN_LENGTH: usize = 128;
function split (line 896) | pub fn split(length: usize, icmp_payload: &[u8]) -> (&[u8], Option<&[u8]...
function test_split_empty_payload (line 947) | fn test_split_empty_payload() {
function test_split_payload_with_compliant_empty_extension (line 956) | fn test_split_payload_with_compliant_empty_extension() {
function test_split_payload_with_compliant_minimal_extension (line 965) | fn test_split_payload_with_compliant_minimal_extension() {
function test_split_payload_with_invalid_rfc4884_length (line 977) | fn test_split_payload_with_invalid_rfc4884_length() {
function test_split_payload_with_compliant_invalid_extension (line 990) | fn test_split_payload_with_compliant_invalid_extension() {
function test_split_extension_ipv4_time_exceeded_non_compliant_mpls (line 1009) | fn test_split_extension_ipv4_time_exceeded_non_compliant_mpls() {
function test_split_extension_ipv4_time_exceeded_compliant_no_extension (line 1081) | fn test_split_extension_ipv4_time_exceeded_compliant_no_extension() {
function test_split_extension_ipv4_time_exceeded_compliant_extension (line 1125) | fn test_split_extension_ipv4_time_exceeded_compliant_extension() {
function test_ipv6 (line 1193) | fn test_ipv6() {
function test_ipv6_2 (line 1277) | fn test_ipv6_2() {
FILE: crates/trippy-packet/src/icmpv4.rs
type IcmpType (line 7) | pub enum IcmpType {
method id (line 17) | pub const fn id(&self) -> u8 {
method from (line 29) | fn from(val: u8) -> Self {
type IcmpCode (line 42) | pub struct IcmpCode(pub u8);
method from (line 45) | fn from(val: u8) -> Self {
type IcmpTimeExceededCode (line 52) | pub enum IcmpTimeExceededCode {
method from (line 62) | fn from(val: IcmpCode) -> Self {
constant TYPE_OFFSET (line 71) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 72) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 73) | const CHECKSUM_OFFSET: usize = 2;
type IcmpPacket (line 79) | pub struct IcmpPacket<'a> {
function new (line 84) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 98) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 113) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 118) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 123) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 128) | pub fn get_checksum(&self) -> u16 {
function set_icmp_type (line 132) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 136) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 140) | pub fn set_checksum(&mut self, val: u16) {
function packet (line 145) | pub fn packet(&self) -> &[u8] {
method fmt (line 151) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 165) | fn test_icmp_type() {
function test_icmp_code (line 186) | fn test_icmp_code() {
function test_checksum (line 201) | fn test_checksum() {
function test_new_insufficient_buffer (line 216) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 227) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 245) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 246) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 247) | const CHECKSUM_OFFSET: usize = 2;
constant IDENTIFIER_OFFSET (line 248) | const IDENTIFIER_OFFSET: usize = 4;
constant SEQUENCE_OFFSET (line 249) | const SEQUENCE_OFFSET: usize = 6;
type EchoRequestPacket (line 256) | pub struct EchoRequestPacket<'a> {
function new (line 261) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 275) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 290) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 295) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 300) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 305) | pub fn get_checksum(&self) -> u16 {
function get_identifier (line 310) | pub fn get_identifier(&self) -> u16 {
function get_sequence (line 315) | pub fn get_sequence(&self) -> u16 {
function set_icmp_type (line 319) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 323) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 327) | pub fn set_checksum(&mut self, val: u16) {
function set_identifier (line 331) | pub fn set_identifier(&mut self, val: u16) {
function set_sequence (line 335) | pub fn set_sequence(&mut self, val: u16) {
function set_payload (line 339) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 346) | pub fn packet(&self) -> &[u8] {
function payload (line 351) | pub fn payload(&self) -> &[u8] {
method fmt (line 357) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 374) | fn test_icmp_type() {
function test_icmp_code (line 395) | fn test_icmp_code() {
function test_checksum (line 410) | fn test_checksum() {
function test_identifier (line 425) | fn test_identifier() {
function test_sequence (line 440) | fn test_sequence() {
function test_view (line 455) | fn test_view() {
function test_new_insufficient_buffer (line 467) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 478) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 497) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 498) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 499) | const CHECKSUM_OFFSET: usize = 2;
constant IDENTIFIER_OFFSET (line 500) | const IDENTIFIER_OFFSET: usize = 4;
constant SEQUENCE_OFFSET (line 501) | const SEQUENCE_OFFSET: usize = 6;
type EchoReplyPacket (line 508) | pub struct EchoReplyPacket<'a> {
function new (line 513) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 527) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 542) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 547) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 552) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 557) | pub fn get_checksum(&self) -> u16 {
function get_identifier (line 562) | pub fn get_identifier(&self) -> u16 {
function get_sequence (line 567) | pub fn get_sequence(&self) -> u16 {
function set_icmp_type (line 571) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 575) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 579) | pub fn set_checksum(&mut self, val: u16) {
function set_identifier (line 583) | pub fn set_identifier(&mut self, val: u16) {
function set_sequence (line 587) | pub fn set_sequence(&mut self, val: u16) {
function set_payload (line 591) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 598) | pub fn packet(&self) -> &[u8] {
function payload (line 603) | pub fn payload(&self) -> &[u8] {
method fmt (line 609) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 626) | fn test_icmp_type() {
function test_icmp_code (line 647) | fn test_icmp_code() {
function test_checksum (line 662) | fn test_checksum() {
function test_identifier (line 677) | fn test_identifier() {
function test_sequence (line 692) | fn test_sequence() {
function test_view (line 707) | fn test_view() {
function test_new_insufficient_buffer (line 719) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 730) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 750) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 751) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 752) | const CHECKSUM_OFFSET: usize = 2;
constant LENGTH_OFFSET (line 753) | const LENGTH_OFFSET: usize = 5;
type TimeExceededPacket (line 760) | pub struct TimeExceededPacket<'a> {
function new (line 765) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 779) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 794) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 799) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 804) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 809) | pub fn get_checksum(&self) -> u16 {
function get_length (line 814) | pub fn get_length(&self) -> u8 {
function set_icmp_type (line 818) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 822) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 826) | pub fn set_checksum(&mut self, val: u16) {
function set_length (line 830) | pub fn set_length(&mut self, val: u8) {
function set_payload (line 834) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 841) | pub fn packet(&self) -> &[u8] {
function payload (line 846) | pub fn payload(&self) -> &[u8] {
function payload_raw (line 852) | pub fn payload_raw(&self) -> &[u8] {
function extension (line 857) | pub fn extension(&self) -> Option<&[u8]> {
function split_payload_extension (line 862) | fn split_payload_extension(&self) -> (&[u8], Option<&[u8]>) {
method fmt (line 873) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 889) | fn test_icmp_type() {
function test_icmp_code (line 910) | fn test_icmp_code() {
function test_checksum (line 925) | fn test_checksum() {
function test_length (line 940) | fn test_length() {
function test_view (line 955) | fn test_view() {
function test_view_large (line 966) | fn test_view_large() {
function test_new_insufficient_buffer (line 979) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 990) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 1010) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 1011) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 1012) | const CHECKSUM_OFFSET: usize = 2;
constant LENGTH_OFFSET (line 1013) | const LENGTH_OFFSET: usize = 5;
constant NEXT_HOP_MTU_OFFSET (line 1014) | const NEXT_HOP_MTU_OFFSET: usize = 6;
type DestinationUnreachablePacket (line 1021) | pub struct DestinationUnreachablePacket<'a> {
function new (line 1026) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 1040) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 1055) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 1060) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 1065) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 1070) | pub fn get_checksum(&self) -> u16 {
function get_length (line 1075) | pub fn get_length(&self) -> u8 {
function get_next_hop_mtu (line 1080) | pub fn get_next_hop_mtu(&self) -> u16 {
function set_icmp_type (line 1084) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 1088) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 1092) | pub fn set_checksum(&mut self, val: u16) {
function set_length (line 1096) | pub fn set_length(&mut self, val: u8) {
function set_next_hop_mtu (line 1100) | pub fn set_next_hop_mtu(&mut self, val: u16) {
function set_payload (line 1104) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 1111) | pub fn packet(&self) -> &[u8] {
function payload (line 1116) | pub fn payload(&self) -> &[u8] {
function payload_raw (line 1122) | pub fn payload_raw(&self) -> &[u8] {
function extension (line 1127) | pub fn extension(&self) -> Option<&[u8]> {
function split_payload_extension (line 1132) | fn split_payload_extension(&self) -> (&[u8], Option<&[u8]>) {
method fmt (line 1140) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 1157) | fn test_icmp_type() {
function test_icmp_code (line 1178) | fn test_icmp_code() {
function test_checksum (line 1193) | fn test_checksum() {
function test_length (line 1208) | fn test_length() {
function test_view (line 1223) | fn test_view() {
function test_view_large (line 1234) | fn test_view_large() {
function test_new_insufficient_buffer (line 1247) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 1262) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/icmpv6.rs
type IcmpType (line 7) | pub enum IcmpType {
method id (line 17) | pub const fn id(&self) -> u8 {
method from (line 29) | fn from(val: u8) -> Self {
type IcmpCode (line 42) | pub struct IcmpCode(pub u8);
method from (line 45) | fn from(val: u8) -> Self {
type IcmpTimeExceededCode (line 52) | pub enum IcmpTimeExceededCode {
method from (line 62) | fn from(val: IcmpCode) -> Self {
constant TYPE_OFFSET (line 71) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 72) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 73) | const CHECKSUM_OFFSET: usize = 2;
type IcmpPacket (line 79) | pub struct IcmpPacket<'a> {
function new (line 84) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 98) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 113) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 118) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 123) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 128) | pub fn get_checksum(&self) -> u16 {
function set_icmp_type (line 132) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 136) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 140) | pub fn set_checksum(&mut self, val: u16) {
function packet (line 145) | pub fn packet(&self) -> &[u8] {
method fmt (line 151) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 165) | fn test_icmp_type() {
function test_icmp_code (line 186) | fn test_icmp_code() {
function test_checksum (line 201) | fn test_checksum() {
function test_new_insufficient_buffer (line 216) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 227) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 245) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 246) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 247) | const CHECKSUM_OFFSET: usize = 2;
constant IDENTIFIER_OFFSET (line 248) | const IDENTIFIER_OFFSET: usize = 4;
constant SEQUENCE_OFFSET (line 249) | const SEQUENCE_OFFSET: usize = 6;
type EchoRequestPacket (line 256) | pub struct EchoRequestPacket<'a> {
function new (line 261) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 275) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 290) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 295) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 300) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 305) | pub fn get_checksum(&self) -> u16 {
function get_identifier (line 310) | pub fn get_identifier(&self) -> u16 {
function get_sequence (line 315) | pub fn get_sequence(&self) -> u16 {
function set_icmp_type (line 319) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 323) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 327) | pub fn set_checksum(&mut self, val: u16) {
function set_identifier (line 331) | pub fn set_identifier(&mut self, val: u16) {
function set_sequence (line 335) | pub fn set_sequence(&mut self, val: u16) {
function set_payload (line 339) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 346) | pub fn packet(&self) -> &[u8] {
function payload (line 351) | pub fn payload(&self) -> &[u8] {
method fmt (line 357) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 374) | fn test_icmp_type() {
function test_icmp_code (line 395) | fn test_icmp_code() {
function test_checksum (line 410) | fn test_checksum() {
function test_identifier (line 425) | fn test_identifier() {
function test_sequence (line 440) | fn test_sequence() {
function test_view (line 455) | fn test_view() {
function test_new_insufficient_buffer (line 467) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 478) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 497) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 498) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 499) | const CHECKSUM_OFFSET: usize = 2;
constant IDENTIFIER_OFFSET (line 500) | const IDENTIFIER_OFFSET: usize = 4;
constant SEQUENCE_OFFSET (line 501) | const SEQUENCE_OFFSET: usize = 6;
type EchoReplyPacket (line 508) | pub struct EchoReplyPacket<'a> {
function new (line 513) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 527) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 542) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 547) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 552) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 557) | pub fn get_checksum(&self) -> u16 {
function get_identifier (line 562) | pub fn get_identifier(&self) -> u16 {
function get_sequence (line 567) | pub fn get_sequence(&self) -> u16 {
function set_icmp_type (line 571) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 575) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 579) | pub fn set_checksum(&mut self, val: u16) {
function set_identifier (line 583) | pub fn set_identifier(&mut self, val: u16) {
function set_sequence (line 587) | pub fn set_sequence(&mut self, val: u16) {
function set_payload (line 591) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 598) | pub fn packet(&self) -> &[u8] {
function payload (line 603) | pub fn payload(&self) -> &[u8] {
method fmt (line 609) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 626) | fn test_icmp_type() {
function test_icmp_code (line 647) | fn test_icmp_code() {
function test_checksum (line 662) | fn test_checksum() {
function test_identifier (line 677) | fn test_identifier() {
function test_sequence (line 692) | fn test_sequence() {
function test_view (line 707) | fn test_view() {
function test_new_insufficient_buffer (line 719) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 730) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 750) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 751) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 752) | const CHECKSUM_OFFSET: usize = 2;
constant LENGTH_OFFSET (line 753) | const LENGTH_OFFSET: usize = 4;
type TimeExceededPacket (line 760) | pub struct TimeExceededPacket<'a> {
function new (line 765) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 779) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 794) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 799) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 804) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 809) | pub fn get_checksum(&self) -> u16 {
function get_length (line 814) | pub fn get_length(&self) -> u8 {
function set_icmp_type (line 818) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 822) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 826) | pub fn set_checksum(&mut self, val: u16) {
function set_length (line 830) | pub fn set_length(&mut self, val: u8) {
function set_payload (line 834) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 841) | pub fn packet(&self) -> &[u8] {
function payload (line 846) | pub fn payload(&self) -> &[u8] {
function payload_raw (line 852) | pub fn payload_raw(&self) -> &[u8] {
function extension (line 857) | pub fn extension(&self) -> Option<&[u8]> {
function split_payload_extension (line 862) | fn split_payload_extension(&self) -> (&[u8], Option<&[u8]>) {
method fmt (line 870) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 886) | fn test_icmp_type() {
function test_icmp_code (line 907) | fn test_icmp_code() {
function test_checksum (line 922) | fn test_checksum() {
function test_length (line 937) | fn test_length() {
function test_view (line 952) | fn test_view() {
function test_view_large (line 963) | fn test_view_large() {
function test_new_insufficient_buffer (line 976) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 987) | fn test_new_view_insufficient_buffer() {
constant TYPE_OFFSET (line 1007) | const TYPE_OFFSET: usize = 0;
constant CODE_OFFSET (line 1008) | const CODE_OFFSET: usize = 1;
constant CHECKSUM_OFFSET (line 1009) | const CHECKSUM_OFFSET: usize = 2;
constant LENGTH_OFFSET (line 1010) | const LENGTH_OFFSET: usize = 4;
constant NEXT_HOP_MTU_OFFSET (line 1011) | const NEXT_HOP_MTU_OFFSET: usize = 6;
type DestinationUnreachablePacket (line 1018) | pub struct DestinationUnreachablePacket<'a> {
function new (line 1023) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 1037) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 1052) | pub const fn minimum_packet_size() -> usize {
function get_icmp_type (line 1057) | pub fn get_icmp_type(&self) -> IcmpType {
function get_icmp_code (line 1062) | pub fn get_icmp_code(&self) -> IcmpCode {
function get_checksum (line 1067) | pub fn get_checksum(&self) -> u16 {
function get_length (line 1072) | pub fn get_length(&self) -> u8 {
function get_next_hop_mtu (line 1077) | pub fn get_next_hop_mtu(&self) -> u16 {
function set_icmp_type (line 1081) | pub fn set_icmp_type(&mut self, val: IcmpType) {
function set_icmp_code (line 1085) | pub fn set_icmp_code(&mut self, val: IcmpCode) {
function set_checksum (line 1089) | pub fn set_checksum(&mut self, val: u16) {
function set_length (line 1093) | pub fn set_length(&mut self, val: u8) {
function set_next_hop_mtu (line 1097) | pub fn set_next_hop_mtu(&mut self, val: u16) {
function set_payload (line 1101) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 1108) | pub fn packet(&self) -> &[u8] {
function payload (line 1113) | pub fn payload(&self) -> &[u8] {
function payload_raw (line 1119) | pub fn payload_raw(&self) -> &[u8] {
function extension (line 1124) | pub fn extension(&self) -> Option<&[u8]> {
function split_payload_extension (line 1129) | fn split_payload_extension(&self) -> (&[u8], Option<&[u8]>) {
method fmt (line 1140) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_icmp_type (line 1157) | fn test_icmp_type() {
function test_icmp_code (line 1178) | fn test_icmp_code() {
function test_checksum (line 1193) | fn test_checksum() {
function test_length (line 1208) | fn test_length() {
function test_view (line 1223) | fn test_view() {
function test_view_large (line 1234) | fn test_view_large() {
function test_new_insufficient_buffer (line 1247) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 1262) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/ip.rs
type IpVersion (line 7) | pub enum IpVersion {
method id (line 15) | pub const fn id(self) -> u8 {
method new (line 24) | pub const fn new(value: u8) -> Self {
method from (line 30) | fn from(id: u8) -> Self {
constant VERSION_OFFSET (line 39) | const VERSION_OFFSET: usize = 0;
type IpPacket (line 45) | pub struct IpPacket<'a> {
function new (line 50) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 64) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 79) | pub const fn minimum_packet_size() -> usize {
function get_version (line 84) | pub fn get_version(&self) -> IpVersion {
function set_version (line 88) | pub fn set_version(&mut self, val: IpVersion) {
function packet (line 94) | pub fn packet(&self) -> &[u8] {
method fmt (line 100) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_version (line 112) | fn test_version() {
function test_view_ipv4_packet (line 127) | fn test_view_ipv4_packet() {
function test_view_ipv6_packet (line 139) | fn test_view_ipv6_packet() {
function test_new_insufficient_buffer (line 152) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 163) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/ipv4.rs
constant VERSION_OFFSET (line 7) | const VERSION_OFFSET: usize = 0;
constant IHL_OFFSET (line 8) | const IHL_OFFSET: usize = 0;
constant DSCP_OFFSET (line 9) | const DSCP_OFFSET: usize = 1;
constant ECN_OFFSET (line 10) | const ECN_OFFSET: usize = 1;
constant TOTAL_LENGTH_OFFSET (line 11) | const TOTAL_LENGTH_OFFSET: usize = 2;
constant IDENTIFICATION_OFFSET (line 12) | const IDENTIFICATION_OFFSET: usize = 4;
constant FLAGS_AND_FRAGMENT_OFFSET_OFFSET (line 13) | const FLAGS_AND_FRAGMENT_OFFSET_OFFSET: usize = 6;
constant TIME_TO_LIVE_OFFSET (line 14) | const TIME_TO_LIVE_OFFSET: usize = 8;
constant PROTOCOL_OFFSET (line 15) | const PROTOCOL_OFFSET: usize = 9;
constant CHECKSUM_OFFSET (line 16) | const CHECKSUM_OFFSET: usize = 10;
constant SOURCE_OFFSET (line 17) | const SOURCE_OFFSET: usize = 12;
constant DESTINATION_OFFSET (line 18) | const DESTINATION_OFFSET: usize = 16;
type Ipv4Packet (line 24) | pub struct Ipv4Packet<'a> {
function new (line 29) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 43) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 58) | pub const fn minimum_packet_size() -> usize {
function get_version (line 63) | pub fn get_version(&self) -> u8 {
function get_header_length (line 68) | pub fn get_header_length(&self) -> u8 {
function get_dscp (line 73) | pub fn get_dscp(&self) -> u8 {
function get_ecn (line 78) | pub fn get_ecn(&self) -> u8 {
function get_tos (line 83) | pub fn get_tos(&self) -> u8 {
function get_total_length (line 88) | pub fn get_total_length(&self) -> u16 {
function get_identification (line 93) | pub fn get_identification(&self) -> u16 {
function get_flags_and_fragment_offset (line 98) | pub fn get_flags_and_fragment_offset(&self) -> u16 {
function get_ttl (line 103) | pub fn get_ttl(&self) -> u8 {
function get_protocol (line 108) | pub fn get_protocol(&self) -> IpProtocol {
function get_checksum (line 113) | pub fn get_checksum(&self) -> u16 {
function get_source (line 118) | pub fn get_source(&self) -> Ipv4Addr {
function get_destination (line 123) | pub fn get_destination(&self) -> Ipv4Addr {
function get_options_raw (line 128) | pub fn get_options_raw(&self) -> &[u8] {
function set_version (line 137) | pub fn set_version(&mut self, val: u8) {
function set_header_length (line 142) | pub fn set_header_length(&mut self, val: u8) {
function set_dscp (line 146) | pub fn set_dscp(&mut self, val: u8) {
function set_ecn (line 150) | pub fn set_ecn(&mut self, val: u8) {
function set_tos (line 154) | pub fn set_tos(&mut self, val: u8) {
function set_total_length (line 159) | pub fn set_total_length(&mut self, val: u16) {
function set_identification (line 163) | pub fn set_identification(&mut self, val: u16) {
function set_flags_and_fragment_offset (line 167) | pub fn set_flags_and_fragment_offset(&mut self, val: u16) {
function set_ttl (line 172) | pub fn set_ttl(&mut self, val: u8) {
function set_protocol (line 176) | pub fn set_protocol(&mut self, val: IpProtocol) {
function set_checksum (line 180) | pub fn set_checksum(&mut self, val: u16) {
function set_source (line 184) | pub fn set_source(&mut self, val: Ipv4Addr) {
function set_destination (line 188) | pub fn set_destination(&mut self, val: Ipv4Addr) {
function get_options_raw_mut (line 192) | pub fn get_options_raw_mut(&mut self) -> &mut [u8] {
function set_payload (line 202) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 208) | pub fn packet(&self) -> &[u8] {
function payload (line 213) | pub fn payload(&self) -> &[u8] {
function ipv4_options_length (line 219) | fn ipv4_options_length(ipv4: &Ipv4Packet<'_>) -> usize {
method fmt (line 224) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_version (line 252) | fn test_version() {
function test_header_length (line 264) | fn test_header_length() {
function test_version_and_header_length (line 276) | fn test_version_and_header_length() {
function test_dscp (line 292) | fn test_dscp() {
function test_ecn (line 301) | fn test_ecn() {
function test_dscp_and_ecn (line 310) | fn test_dscp_and_ecn() {
function test_tos (line 321) | fn test_tos() {
function test_total_length (line 337) | fn test_total_length() {
function test_identification (line 349) | fn test_identification() {
function test_flags (line 361) | fn test_flags() {
function test_time_to_live (line 374) | fn test_time_to_live() {
function test_protocol (line 386) | fn test_protocol() {
function test_header_checksum (line 410) | fn test_header_checksum() {
function test_source (line 425) | fn test_source() {
function test_destination (line 443) | fn test_destination() {
function test_view (line 464) | fn test_view() {
function test_new_insufficient_buffer (line 489) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 500) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/ipv6.rs
constant VERSION_OFFSET (line 7) | const VERSION_OFFSET: usize = 0;
constant TRAFFIC_CLASS_OFFSET (line 8) | const TRAFFIC_CLASS_OFFSET: usize = 0;
constant FLOW_LABEL_OFFSET (line 9) | const FLOW_LABEL_OFFSET: usize = 1;
constant PAYLOAD_LENGTH_OFFSET (line 10) | const PAYLOAD_LENGTH_OFFSET: usize = 4;
constant NEXT_HEADER_OFFSET (line 11) | const NEXT_HEADER_OFFSET: usize = 6;
constant HOP_LIMIT_OFFSET (line 12) | const HOP_LIMIT_OFFSET: usize = 7;
constant SOURCE_ADDRESS_OFFSET (line 13) | const SOURCE_ADDRESS_OFFSET: usize = 8;
constant DESTINATION_ADDRESS_OFFSET (line 14) | const DESTINATION_ADDRESS_OFFSET: usize = 24;
type Ipv6Packet (line 20) | pub struct Ipv6Packet<'a> {
function new (line 25) | pub fn new(packet: &'a mut [u8]) -> Result<Self> {
function new_view (line 39) | pub fn new_view(packet: &'a [u8]) -> Result<Self> {
function minimum_packet_size (line 54) | pub const fn minimum_packet_size() -> usize {
function get_version (line 59) | pub fn get_version(&self) -> u8 {
function get_traffic_class (line 64) | pub fn get_traffic_class(&self) -> u8 {
function get_flow_label (line 71) | pub fn get_flow_label(&self) -> u32 {
function get_payload_length (line 79) | pub fn get_payload_length(&self) -> u16 {
function get_next_header (line 84) | pub fn get_next_header(&self) -> IpProtocol {
function get_hop_limit (line 89) | pub fn get_hop_limit(&self) -> u8 {
function get_source_address (line 94) | pub fn get_source_address(&self) -> Ipv6Addr {
function get_destination_address (line 99) | pub fn get_destination_address(&self) -> Ipv6Addr {
function set_version (line 103) | pub fn set_version(&mut self, val: u8) {
function set_traffic_class (line 108) | pub fn set_traffic_class(&mut self, val: u8) {
function set_flow_label (line 115) | pub fn set_flow_label(&mut self, val: u32) {
function set_payload_length (line 122) | pub fn set_payload_length(&mut self, val: u16) {
function set_next_header (line 126) | pub fn set_next_header(&mut self, val: IpProtocol) {
function set_hop_limit (line 130) | pub fn set_hop_limit(&mut self, val: u8) {
function set_source_address (line 134) | pub fn set_source_address(&mut self, val: Ipv6Addr) {
function set_destination_address (line 138) | pub fn set_destination_address(&mut self, val: Ipv6Addr) {
function set_payload (line 142) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 152) | pub fn packet(&self) -> &[u8] {
function payload (line 157) | pub fn payload(&self) -> &[u8] {
method fmt (line 171) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_version (line 192) | fn test_version() {
function test_traffic_class (line 204) | fn test_traffic_class() {
function test_version_and_traffic_class (line 216) | fn test_version_and_traffic_class() {
function test_flow_label (line 227) | fn test_flow_label() {
function test_payload_length (line 242) | fn test_payload_length() {
function test_next_header (line 257) | fn test_next_header() {
function test_hop_limit (line 281) | fn test_hop_limit() {
function test_source_address (line 296) | fn test_source_address() {
function test_destination_address (line 323) | fn test_destination_address() {
function test_view (line 350) | fn test_view() {
function test_new_insufficient_buffer (line 375) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 386) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/lib.rs
type IpProtocol (line 93) | pub enum IpProtocol {
method id (line 103) | pub const fn id(self) -> u8 {
method new (line 114) | pub const fn new(value: u8) -> Self {
method from (line 120) | fn from(id: u8) -> Self {
function fmt_payload (line 133) | pub fn fmt_payload(bytes: &[u8]) -> String {
FILE: crates/trippy-packet/src/tcp.rs
constant SOURCE_PORT_OFFSET (line 6) | const SOURCE_PORT_OFFSET: usize = 0;
constant DESTINATION_PORT_OFFSET (line 7) | const DESTINATION_PORT_OFFSET: usize = 2;
constant SEQUENCE_OFFSET (line 8) | const SEQUENCE_OFFSET: usize = 4;
constant ACKNOWLEDGEMENT_OFFSET (line 9) | const ACKNOWLEDGEMENT_OFFSET: usize = 8;
constant DATA_OFFSET_OFFSET (line 10) | const DATA_OFFSET_OFFSET: usize = 12;
constant RESERVED_OFFSET (line 11) | const RESERVED_OFFSET: usize = 12;
constant FLAGS_OFFSET (line 12) | const FLAGS_OFFSET: usize = 12;
constant WINDOW_SIZE_OFFSET (line 13) | const WINDOW_SIZE_OFFSET: usize = 14;
constant CHECKSUM_OFFSET (line 14) | const CHECKSUM_OFFSET: usize = 16;
constant URGENT_POINTER_OFFSET (line 15) | const URGENT_POINTER_OFFSET: usize = 18;
type TcpPacket (line 21) | pub struct TcpPacket<'a> {
function new (line 26) | pub fn new(packet: &mut [u8]) -> Result<TcpPacket<'_>> {
function new_view (line 40) | pub fn new_view(packet: &[u8]) -> Result<TcpPacket<'_>> {
function minimum_packet_size (line 55) | pub const fn minimum_packet_size() -> usize {
function get_source (line 60) | pub fn get_source(&self) -> u16 {
function get_destination (line 65) | pub fn get_destination(&self) -> u16 {
function get_sequence (line 70) | pub fn get_sequence(&self) -> u32 {
function get_acknowledgement (line 75) | pub fn get_acknowledgement(&self) -> u32 {
function get_data_offset (line 80) | pub fn get_data_offset(&self) -> u8 {
function get_reserved (line 85) | pub fn get_reserved(&self) -> u8 {
function get_flags (line 90) | pub fn get_flags(&self) -> u16 {
function get_window_size (line 98) | pub fn get_window_size(&self) -> u16 {
function get_checksum (line 103) | pub fn get_checksum(&self) -> u16 {
function get_urgent_pointer (line 108) | pub fn get_urgent_pointer(&self) -> u16 {
function get_options_raw (line 113) | pub fn get_options_raw(&self) -> &[u8] {
function set_source (line 122) | pub fn set_source(&mut self, val: u16) {
function set_destination (line 126) | pub fn set_destination(&mut self, val: u16) {
function set_sequence (line 131) | pub fn set_sequence(&mut self, val: u32) {
function set_acknowledgement (line 135) | pub fn set_acknowledgement(&mut self, val: u32) {
function set_data_offset (line 140) | pub fn set_data_offset(&mut self, val: u8) {
function set_reserved (line 145) | pub fn set_reserved(&mut self, val: u8) {
function set_flags (line 150) | pub fn set_flags(&mut self, val: u16) {
function set_window_size (line 156) | pub fn set_window_size(&mut self, val: u16) {
function set_checksum (line 160) | pub fn set_checksum(&mut self, val: u16) {
function set_urgent_pointer (line 164) | pub fn set_urgent_pointer(&mut self, val: u16) {
function set_payload (line 168) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 174) | pub fn packet(&self) -> &[u8] {
function payload (line 179) | pub fn payload(&self) -> &[u8] {
function tcp_options_length (line 187) | fn tcp_options_length(&self) -> usize {
method fmt (line 198) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_source (line 221) | fn test_source() {
function test_destination (line 239) | fn test_destination() {
function test_sequence (line 257) | fn test_sequence() {
function test_acknowledgement (line 272) | fn test_acknowledgement() {
function test_data_offset (line 287) | fn test_data_offset() {
function test_reserved (line 299) | fn test_reserved() {
function test_flags (line 311) | fn test_flags() {
function test_data_offset_and_reserved (line 323) | fn test_data_offset_and_reserved() {
function test_reserved_and_flags (line 339) | fn test_reserved_and_flags() {
function test_data_offset_and_reserved_and_flags (line 353) | fn test_data_offset_and_reserved_and_flags() {
function test_window_size (line 369) | fn test_window_size() {
function test_checksum (line 387) | fn test_checksum() {
function test_urgent_pointer (line 405) | fn test_urgent_pointer() {
function test_view (line 423) | fn test_view() {
function test_new_insufficient_buffer (line 451) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 462) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-packet/src/udp.rs
constant SOURCE_PORT_OFFSET (line 6) | const SOURCE_PORT_OFFSET: usize = 0;
constant DESTINATION_PORT_OFFSET (line 7) | const DESTINATION_PORT_OFFSET: usize = 2;
constant LENGTH_OFFSET (line 8) | const LENGTH_OFFSET: usize = 4;
constant CHECKSUM_OFFSET (line 9) | const CHECKSUM_OFFSET: usize = 6;
type UdpPacket (line 15) | pub struct UdpPacket<'a> {
function new (line 20) | pub fn new(packet: &mut [u8]) -> Result<UdpPacket<'_>> {
function new_view (line 34) | pub fn new_view(packet: &[u8]) -> Result<UdpPacket<'_>> {
function minimum_packet_size (line 49) | pub const fn minimum_packet_size() -> usize {
function get_source (line 54) | pub fn get_source(&self) -> u16 {
function get_destination (line 59) | pub fn get_destination(&self) -> u16 {
function get_length (line 64) | pub fn get_length(&self) -> u16 {
function get_checksum (line 69) | pub fn get_checksum(&self) -> u16 {
function set_source (line 73) | pub fn set_source(&mut self, val: u16) {
function set_destination (line 77) | pub fn set_destination(&mut self, val: u16) {
function set_length (line 82) | pub fn set_length(&mut self, val: u16) {
function set_checksum (line 86) | pub fn set_checksum(&mut self, val: u16) {
function set_payload (line 90) | pub fn set_payload(&mut self, vals: &[u8]) {
function packet (line 96) | pub fn packet(&self) -> &[u8] {
function payload (line 101) | pub fn payload(&self) -> &[u8] {
method fmt (line 107) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_source (line 123) | fn test_source() {
function test_destination (line 141) | fn test_destination() {
function test_length (line 159) | fn test_length() {
function test_checksum (line 177) | fn test_checksum() {
function test_view (line 195) | fn test_view() {
function test_new_insufficient_buffer (line 206) | fn test_new_insufficient_buffer() {
function test_new_view_insufficient_buffer (line 217) | fn test_new_view_insufficient_buffer() {
FILE: crates/trippy-privilege/src/lib.rs
type Result (line 86) | pub type Result<T> = std::result::Result<T, Error>;
type Error (line 90) | pub enum Error {
type Privilege (line 104) | pub struct Privilege {
method discover (line 111) | pub fn discover() -> Result<Self> {
method new (line 122) | pub const fn new(has_privileges: bool, needs_privileges: bool) -> Self {
method has_privileges (line 131) | pub const fn has_privileges(&self) -> bool {
method needs_privileges (line 140) | pub const fn needs_privileges(&self) -> bool {
method acquire_privileges (line 150) | pub fn acquire_privileges() -> Result<Self> {
method check_has_privileges (line 161) | fn check_has_privileges() -> Result<bool> {
method drop_privileges (line 173) | pub fn drop_privileges() -> Result<()> {
method acquire_privileges (line 184) | pub fn acquire_privileges() -> Result<Self> {
method check_has_privileges (line 193) | fn check_has_privileges() -> Result<bool> {
method drop_privileges (line 201) | pub const fn drop_privileges() -> Result<()> {
method check_needs_privileges (line 215) | const fn check_needs_privileges() -> bool {
method check_needs_privileges (line 225) | const fn check_needs_privileges() -> bool {
method acquire_privileges (line 235) | pub fn acquire_privileges() -> Result<Self> {
method check_has_privileges (line 243) | fn check_has_privileges() -> Result<bool> {
method drop_privileges (line 313) | pub const fn drop_privileges() -> Result<()> {
method check_needs_privileges (line 321) | const fn check_needs_privileges() -> bool {
FILE: crates/trippy-tui/build.rs
function main (line 1) | pub fn main() {
FILE: crates/trippy-tui/src/app.rs
function run_trippy (line 18) | pub fn run_trippy(cfg: &TrippyConfig, pid: u16) -> anyhow::Result<()> {
function start_tracers (line 39) | fn start_tracers(
function start_tracer (line 55) | fn start_tracer(
function run_frontend (line 93) | fn run_frontend(
function resolve_targets (line 121) | fn resolve_targets(cfg: &TrippyConfig, resolver: &DnsResolver) -> anyhow...
function start_dns_resolver (line 146) | fn start_dns_resolver(cfg: &TrippyConfig) -> anyhow::Result<DnsResolver> {
function create_geoip_lookup (line 156) | fn create_geoip_lookup(cfg: &TrippyConfig, locale: &str) -> anyhow::Resu...
function configure_logging (line 164) | fn configure_logging(cfg: &TrippyConfig) -> Option<FlushGuard> {
function make_tui_config (line 207) | fn make_tui_config(args: &TrippyConfig, locale: String) -> TuiConfig {
function make_trace_info (line 229) | const fn make_trace_info(tracer: Tracer, target: String) -> TraceInfo {
type TraceInfo (line 235) | pub struct TraceInfo {
method new (line 242) | pub const fn new(data: Tracer, target_hostname: String) -> Self {
type TargetInfo (line 252) | struct TargetInfo {
FILE: crates/trippy-tui/src/config.rs
type Mode (line 34) | pub enum Mode {
type ProtocolConfig (line 58) | pub enum ProtocolConfig {
method from (line 68) | fn from(value: Protocol) -> Self {
type AddressFamilyConfig (line 80) | pub enum AddressFamilyConfig {
method from (line 97) | fn from(value: IpAddrFamily) -> Self {
type MultipathStrategyConfig (line 111) | pub enum MultipathStrategyConfig {
method from (line 121) | fn from(value: MultipathStrategy) -> Self {
type AddressMode (line 133) | pub enum AddressMode {
type AsMode (line 145) | pub enum AsMode {
type IcmpExtensionMode (line 163) | pub enum IcmpExtensionMode {
type GeoIpMode (line 185) | pub enum GeoIpMode {
type DnsResolveMethodConfig (line 212) | pub enum DnsResolveMethodConfig {
type LogFormat (line 226) | pub enum LogFormat {
type LogSpanEvents (line 240) | pub enum LogSpanEvents {
type TrippyAction (line 251) | pub enum TrippyAction {
method from (line 269) | pub fn from(args: Args, privilege: &Privilege, pid: u16) -> anyhow::Re...
type TrippyConfig (line 290) | pub struct TrippyConfig {
method from (line 342) | pub fn from(args: Args, privilege: &Privilege, pid: u16) -> anyhow::Re...
method max_flows (line 354) | pub const fn max_flows(&self) -> usize {
method build_config (line 362) | fn build_config(
method default (line 728) | fn default() -> Self {
function dns_resolve_method (line 782) | const fn dns_resolve_method(dns_resolve_method: DnsResolveMethodConfig) ...
function dns_resolve_family (line 791) | const fn dns_resolve_family(dns_resolve_family: AddressFamilyConfig) -> ...
function cfg_layer (line 801) | fn cfg_layer<T>(fst: Option<T>, snd: Option<T>, def: T) -> T {
function cfg_layer_opt (line 808) | fn cfg_layer_opt<T>(fst: Option<T>, snd: Option<T>) -> Option<T> {
function cfg_layer_bool_flag (line 815) | const fn cfg_layer_bool_flag(fst: bool, snd: Option<bool>, default: bool...
function validate_deprecated (line 824) | fn validate_deprecated(
function validate_privilege (line 846) | fn validate_privilege(
function validate_tui_custom_columns (line 870) | fn validate_tui_custom_columns(tui_custom_columns: &TuiColumns) -> anyho...
function validate_logging (line 885) | fn validate_logging(mode: Mode, verbose: bool) -> anyhow::Result<()> {
function validate_strategy (line 894) | fn validate_strategy(strategy: MultipathStrategy, unprivileged: bool) ->...
function validate_protocol_strategy (line 907) | fn validate_protocol_strategy(
function validate_multi (line 929) | fn validate_multi(
function validate_flows (line 952) | fn validate_flows(mode: Mode, strategy: MultipathStrategy) -> anyhow::Re...
function validate_ttl (line 962) | fn validate_ttl(first_ttl: u8, max_ttl: u8) -> anyhow::Result<()> {
function validate_max_inflight (line 981) | fn validate_max_inflight(max_inflight: u8) -> anyhow::Result<()> {
function validate_read_timeout (line 992) | fn validate_read_timeout(read_timeout: Duration) -> anyhow::Result<()> {
function validate_round_duration (line 1008) | fn validate_round_duration(
function validate_grace_duration (line 1022) | fn validate_grace_duration(grace_duration: Duration) -> anyhow::Result<(...
function validate_packet_size (line 1038) | fn validate_packet_size(address_family: IpAddrFamily, packet_size: u16) ...
function validate_source_port (line 1060) | fn validate_source_port(source_port: u16) -> anyhow::Result<()> {
function validate_tui_refresh_rate (line 1069) | fn validate_tui_refresh_rate(tui_refresh_rate: Duration) -> anyhow::Resu...
function validate_report_cycles (line 1085) | fn validate_report_cycles(report_cycles: usize) -> anyhow::Result<()> {
function validate_dns (line 1096) | fn validate_dns(dns_resolve_method: ResolveMethod, dns_lookup_as_info: b...
function validate_geoip (line 1105) | fn validate_geoip(
function validate_bindings (line 1123) | fn validate_bindings(bindings: &TuiBindings) -> anyhow::Result<()> {
function validate_tos (line 1134) | fn validate_tos(address_family: IpAddrFamily, tos: u8) -> anyhow::Result...
function test_config_default (line 1155) | fn test_config_default() {
function test_config_sample (line 1168) | fn test_config_sample() {
function test_help (line 1184) | fn test_help(cmd: &str) {
function test_version_help (line 1190) | fn test_version_help(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_config (line 1196) | fn test_config(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_mode (line 1214) | fn test_mode(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_target (line 1225) | fn test_target(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_unexpected (line 1230) | fn test_unexpected(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_multipath (line 1244) | fn test_multipath(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_protocol (line 1260) | fn test_protocol(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_ports (line 1280) | fn test_ports(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_addr_family (line 1295) | fn test_addr_family(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_ttl (line 1311) | fn test_ttl(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_round_duration (line 1325) | fn test_round_duration(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_grace_duration (line 1335) | fn test_grace_duration(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_max_inflight (line 1345) | fn test_max_inflight(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_init_seq (line 1353) | fn test_init_seq(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tos (line 1363) | fn test_tos(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_icmp_extensions (line 1370) | fn test_icmp_extensions(cmd: &str, expected: anyhow::Result<TrippyConfig...
function test_read_timeout (line 1379) | fn test_read_timeout(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_packet_size (line 1393) | fn test_packet_size(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_payload_pattern (line 1401) | fn test_payload_pattern(cmd: &str, expected: anyhow::Result<TrippyConfig...
function test_source_address (line 1410) | fn test_source_address(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_interface (line 1417) | fn test_interface(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_dns_timeout (line 1424) | fn test_dns_timeout(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_dns_ttl (line 1431) | fn test_dns_ttl(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_dns_resolve (line 1442) | fn test_dns_resolve(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_dns_resolve_all (line 1449) | fn test_dns_resolve_all(cmd: &str, expected: anyhow::Result<TrippyConfig...
function test_lookup_as_info (line 1457) | fn test_lookup_as_info(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_max_samples (line 1465) | fn test_max_samples(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_max_flows (line 1472) | fn test_max_flows(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_preserve_screen (line 1478) | fn test_tui_preserve_screen(cmd: &str, expected: anyhow::Result<TrippyCo...
function test_tui_refresh_rate (line 1488) | fn test_tui_refresh_rate(cmd: &str, expected: anyhow::Result<TrippyConfi...
function test_tui_privacy_max_ttl (line 1495) | fn test_tui_privacy_max_ttl(cmd: &str, expected: anyhow::Result<TrippyCo...
function test_tui_locale (line 1501) | fn test_tui_locale(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_timezone (line 1509) | fn test_tui_timezone(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_address_mode (line 1519) | fn test_tui_address_mode(cmd: &str, expected: anyhow::Result<TrippyConfi...
function test_tui_as_mode (line 1531) | fn test_tui_as_mode(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_custom_columns (line 1539) | fn test_tui_custom_columns(cmd: &str, expected: anyhow::Result<TrippyCon...
function test_tui_icmp_extension_mode (line 1549) | fn test_tui_icmp_extension_mode(cmd: &str, expected: anyhow::Result<Trip...
function test_tui_geoip_mode (line 1560) | fn test_tui_geoip_mode(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_max_addrs (line 1568) | fn test_tui_max_addrs(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_theme (line 1581) | fn test_tui_theme(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_tui_bindings (line 1592) | fn test_tui_bindings(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_report_cycles (line 1601) | fn test_report_cycles(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_geoip_mmdb_file (line 1608) | fn test_geoip_mmdb_file(cmd: &str, expected: anyhow::Result<TrippyConfig...
function test_verbose (line 1616) | fn test_verbose(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_log_filter (line 1622) | fn test_log_filter(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_log_format (line 1632) | fn test_log_format(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_log_span (line 1641) | fn test_log_span(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function test_privilege (line 1656) | fn test_privilege(
function test_action (line 1679) | fn test_action(cmd: &str, expected: anyhow::Result<TrippyAction>) {
function test_deprecated (line 1686) | fn test_deprecated(cmd: &str, expected: anyhow::Result<TrippyConfig>) {
function parse_action (line 1690) | fn parse_action(cmd: &str) -> anyhow::Result<TrippyAction> {
function parse_config (line 1694) | fn parse_config(cmd: &str) -> anyhow::Result<TrippyConfig> {
function parse_config_with_privileges (line 1701) | fn parse_config_with_privileges(
function parse (line 1712) | fn parse(cmd: &str) -> anyhow::Result<Args> {
function compare (line 1719) | fn compare<T>(actual: anyhow::Result<T>, expected: anyhow::Result<T>)
function compare_lines (line 1726) | fn compare_lines<T>(
function compare_snapshot (line 1769) | fn compare_snapshot<T>(name: &str, actual: anyhow::Result<T>)
function cfg (line 1783) | fn cfg() -> TrippyConfigBuilder {
function cfg_multi (line 1787) | fn cfg_multi() -> TrippyConfigBuilder {
function dummy_platform (line 1795) | const fn dummy_platform() -> Privilege {
function args (line 1799) | fn args(args: &[&str]) -> anyhow::Result<Args> {
type TrippyConfigBuilder (line 1806) | pub struct TrippyConfigBuilder {
method new (line 1811) | pub fn new(targets: Vec<String>) -> Self {
method mode (line 1820) | pub fn mode(self, mode: Mode) -> Self {
method privilege_mode (line 1829) | pub fn privilege_mode(self, privilege_mode: PrivilegeMode) -> Self {
method protocol (line 1838) | pub fn protocol(self, protocol: Protocol) -> Self {
method addr_family (line 1847) | pub fn addr_family(self, addr_family: IpAddrFamily) -> Self {
method first_ttl (line 1856) | pub fn first_ttl(self, first_ttl: u8) -> Self {
method max_ttl (line 1865) | pub fn max_ttl(self, max_ttl: u8) -> Self {
method min_round_duration (line 1874) | pub fn min_round_duration(self, min_round_duration: Duration) -> Self {
method max_round_duration (line 1883) | pub fn max_round_duration(self, max_round_duration: Duration) -> Self {
method grace_duration (line 1892) | pub fn grace_duration(self, grace_duration: Duration) -> Self {
method max_inflight (line 1901) | pub fn max_inflight(self, max_inflight: u8) -> Self {
method initial_sequence (line 1910) | pub fn initial_sequence(self, initial_sequence: u16) -> Self {
method tos (line 1919) | pub fn tos(self, tos: u8) -> Self {
method icmp_extension_parse_mode (line 1925) | pub fn icmp_extension_parse_mode(
method read_timeout (line 1937) | pub fn read_timeout(self, read_timeout: Duration) -> Self {
method packet_size (line 1946) | pub fn packet_size(self, packet_size: u16) -> Self {
method payload_pattern (line 1955) | pub fn payload_pattern(self, payload_pattern: u8) -> Self {
method source_addr (line 1964) | pub fn source_addr(self, source_addr: Option<IpAddr>) -> Self {
method interface (line 1973) | pub fn interface(self, interface: Option<String>) -> Self {
method port_direction (line 1982) | pub fn port_direction(self, port_direction: PortDirection) -> Self {
method multipath_strategy (line 1991) | pub fn multipath_strategy(self, multipath_strategy: MultipathStrategy)...
method dns_timeout (line 2000) | pub fn dns_timeout(self, dns_timeout: Duration) -> Self {
method dns_ttl (line 2009) | pub fn dns_ttl(self, dns_ttl: Duration) -> Self {
method dns_resolve_method (line 2018) | pub fn dns_resolve_method(self, dns_resolve_method: ResolveMethod) -> ...
method dns_lookup_as_info (line 2027) | pub fn dns_lookup_as_info(self, dns_lookup_as_info: bool) -> Self {
method dns_resolve_all (line 2036) | pub fn dns_resolve_all(self, dns_resolve_all: bool) -> Self {
method max_samples (line 2045) | pub fn max_samples(self, tui_max_samples: usize) -> Self {
method max_flows (line 2054) | pub fn max_flows(self, max_flows: usize) -> Self {
method tui_preserve_screen (line 2063) | pub fn tui_preserve_screen(self, tui_preserve_screen: bool) -> Self {
method tui_refresh_rate (line 2072) | pub fn tui_refresh_rate(self, tui_refresh_rate: Duration) -> Self {
method tui_privacy_max_ttl (line 2081) | pub fn tui_privacy_max_ttl(self, tui_privacy_max_ttl: Option<u8>) -> S...
method tui_locale (line 2090) | pub fn tui_locale(self, tui_locale: Option<String>) -> Self {
method tui_timezone (line 2099) | pub fn tui_timezone(self, tui_timezone: Option<chrono_tz::Tz>) -> Self {
method tui_address_mode (line 2108) | pub fn tui_address_mode(self, tui_address_mode: AddressMode) -> Self {
method tui_as_mode (line 2117) | pub fn tui_as_mode(self, tui_as_mode: AsMode) -> Self {
method tui_custom_columns (line 2126) | pub fn tui_custom_columns(self, tui_custom_columns: TuiColumns) -> Self {
method tui_icmp_extension_mode (line 2135) | pub fn tui_icmp_extension_mode(self, tui_icmp_extension_mode: IcmpExte...
method tui_geoip_mode (line 2144) | pub fn tui_geoip_mode(self, tui_geoip_mode: GeoIpMode) -> Self {
method tui_max_addrs (line 2153) | pub fn tui_max_addrs(self, tui_max_addrs: Option<u8>) -> Self {
method tui_theme (line 2162) | pub fn tui_theme(self, tui_theme: TuiTheme) -> Self {
method tui_bindings (line 2172) | pub fn tui_bindings(self, tui_bindings: TuiBindings) -> Self {
method report_cycles (line 2181) | pub fn report_cycles(self, report_cycles: usize) -> Self {
method geoip_mmdb_file (line 2190) | pub fn geoip_mmdb_file(self, geoip_mmdb_file: Option<String>) -> Self {
method max_rounds (line 2199) | pub fn max_rounds(self, max_rounds: Option<usize>) -> Self {
method verbose (line 2208) | pub fn verbose(self, verbose: bool) -> Self {
method log_format (line 2217) | pub fn log_format(self, log_format: LogFormat) -> Self {
method log_filter (line 2226) | pub fn log_filter(self, log_filter: String) -> Self {
method log_span_events (line 2235) | pub fn log_span_events(self, log_span_events: LogSpanEvents) -> Self {
method build (line 2244) | pub fn build(self) -> TrippyConfig {
FILE: crates/trippy-tui/src/config/binding.rs
type TuiBindings (line 12) | pub struct TuiBindings {
method find_duplicates (line 114) | pub fn find_duplicates(&self) -> Vec<String> {
method from (line 187) | fn from(value: (HashMap<TuiCommandItem, TuiKeyBinding>, ConfigBindings...
method default (line 54) | fn default() -> Self {
type TuiKeyBinding (line 349) | pub struct TuiKeyBinding {
method new (line 355) | pub const fn new(code: KeyCode) -> Self {
method new_with_modifier (line 362) | pub const fn new_with_modifier(code: KeyCode, modifier: KeyModifiers) ...
type Error (line 368) | type Error = anyhow::Error;
method try_from (line 370) | fn try_from(value: String) -> Result<Self, Self::Error> {
type Error (line 376) | type Error = anyhow::Error;
method try_from (line 378) | fn try_from(value: &str) -> Result<Self, Self::Error> {
function test_key_binding (line 484) | fn test_key_binding(input: &str, code: KeyCode, modifiers: KeyModifiers)...
function test_unknown_modifier (line 492) | fn test_unknown_modifier() {
function test_unknown_second_modifier (line 499) | fn test_unknown_second_modifier() {
function test_unknown_key (line 506) | fn test_unknown_key() {
method fmt (line 517) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type TuiCommandItem (line 563) | pub enum TuiCommandItem {
FILE: crates/trippy-tui/src/config/cmd.rs
type Args (line 19) | pub struct Args {
function parse_tui_theme_color_value (line 296) | fn parse_tui_theme_color_value(value: &str) -> anyhow::Result<(TuiThemeI...
function parse_tui_binding_value (line 305) | fn parse_tui_binding_value(value: &str) -> anyhow::Result<(TuiCommandIte...
function parse_duration (line 319) | fn parse_duration(value: &str) -> anyhow::Result<Duration> {
function parse_addr (line 323) | fn parse_addr(value: &str) -> anyhow::Result<IpAddr> {
FILE: crates/trippy-tui/src/config/columns.rs
type TuiColumns (line 8) | pub struct TuiColumns(pub Vec<TuiColumn>);
type Error (line 11) | type Error = anyhow::Error;
method try_from (line 13) | fn try_from(value: &str) -> Result<Self, Self::Error> {
method find_duplicates (line 33) | pub fn find_duplicates(&self) -> Vec<String> {
method default (line 24) | fn default() -> Self {
type TuiColumn (line 51) | pub enum TuiColumn {
type Error (line 111) | type Error = anyhow::Error;
method try_from (line 113) | fn try_from(value: char) -> Result<Self, Self::Error> {
method fmt (line 149) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function test_try_from_char_for_tui_column (line 201) | fn test_try_from_char_for_tui_column(c: char, t: TuiColumn) {
function test_try_invalid_char_for_tui_column (line 208) | fn test_try_invalid_char_for_tui_column(c: char) {
function test_display_formatting_for_tui_column (line 226) | fn test_display_formatting_for_tui_column(t: TuiColumn, letter: &'static...
function test_try_from_str_for_tui_columns (line 231) | fn test_try_from_str_for_tui_columns() {
function test_default_for_tui_columns (line 245) | fn test_default_for_tui_columns() {
function test_find_duplicates_for_tui_columns (line 266) | fn test_find_duplicates_for_tui_columns() {
FILE: crates/trippy-tui/src/config/constants.rs
constant DEFAULT_MODE (line 8) | pub const DEFAULT_MODE: Mode = Mode::Tui;
constant DEFAULT_DNS_RESOLVE_ALL (line 11) | pub const DEFAULT_DNS_RESOLVE_ALL: bool = false;
constant DEFAULT_LOG_FORMAT (line 14) | pub const DEFAULT_LOG_FORMAT: LogFormat = LogFormat::Pretty;
constant DEFAULT_LOG_SPAN_EVENTS (line 17) | pub const DEFAULT_LOG_SPAN_EVENTS: LogSpanEvents = LogSpanEvents::Off;
constant DEFAULT_LOG_FILTER (line 20) | pub const DEFAULT_LOG_FILTER: &str = "trippy=debug";
constant DEFAULT_TUI_PRESERVE_SCREEN (line 23) | pub const DEFAULT_TUI_PRESERVE_SCREEN: bool = false;
constant DEFAULT_TUI_AS_MODE (line 26) | pub const DEFAULT_TUI_AS_MODE: AsMode = AsMode::Asn;
constant DEFAULT_CUSTOM_COLUMNS (line 29) | pub const DEFAULT_CUSTOM_COLUMNS: &str = "holsravbwdt";
constant DEFAULT_TUI_ICMP_EXTENSION_MODE (line 32) | pub const DEFAULT_TUI_ICMP_EXTENSION_MODE: IcmpExtensionMode = IcmpExten...
constant DEFAULT_TUI_GEOIP_MODE (line 35) | pub const DEFAULT_TUI_GEOIP_MODE: GeoIpMode = GeoIpMode::Off;
constant DEFAULT_TUI_MAX_ADDRS (line 38) | pub const DEFAULT_TUI_MAX_ADDRS: u8 = 0;
constant DEFAULT_TUI_ADDRESS_MODE (line 41) | pub const DEFAULT_TUI_ADDRESS_MODE: AddressMode = AddressMode::Host;
constant DEFAULT_TUI_REFRESH_RATE (line 44) | pub const DEFAULT_TUI_REFRESH_RATE: Duration = Duration::from_millis(100);
constant DEFAULT_DNS_RESOLVE_METHOD (line 47) | pub const DEFAULT_DNS_RESOLVE_METHOD: DnsResolveMethodConfig = DnsResolv...
constant DEFAULT_ADDR_FAMILY (line 50) | pub const DEFAULT_ADDR_FAMILY: AddressFamilyConfig = AddressFamilyConfig...
constant DEFAULT_DNS_LOOKUP_AS_INFO (line 53) | pub const DEFAULT_DNS_LOOKUP_AS_INFO: bool = false;
constant DEFAULT_DNS_TIMEOUT (line 56) | pub const DEFAULT_DNS_TIMEOUT: Duration = Duration::from_millis(5000);
constant DEFAULT_DNS_TTL (line 59) | pub const DEFAULT_DNS_TTL: Duration = Duration::from_secs(300);
constant DEFAULT_REPORT_CYCLES (line 62) | pub const DEFAULT_REPORT_CYCLES: usize = 10;
constant TUI_MIN_REFRESH_RATE_MS (line 65) | pub const TUI_MIN_REFRESH_RATE_MS: Duration = Duration::from_millis(50);
constant TUI_MAX_REFRESH_RATE_MS (line 68) | pub const TUI_MAX_REFRESH_RATE_MS: Duration = Duration::from_millis(1000);
constant MIN_READ_TIMEOUT_MS (line 71) | pub const MIN_READ_TIMEOUT_MS: Duration = Duration::from_millis(10);
constant MAX_READ_TIMEOUT_MS (line 74) | pub const MAX_READ_TIMEOUT_MS: Duration = Duration::from_millis(100);
constant MIN_GRACE_DURATION_MS (line 77) | pub const MIN_GRACE_DURATION_MS: Duration = Duration::from_millis(10);
constant MAX_GRACE_DURATION_MS (line 80) | pub const MAX_GRACE_DURATION_MS: Duration = Duration::from_millis(1000);
constant MIN_PACKET_SIZE_IPV4 (line 83) | pub const MIN_PACKET_SIZE_IPV4: u16 = 28;
constant MIN_PACKET_SIZE_IPV6 (line 86) | pub const MIN_PACKET_SIZE_IPV6: u16 = 48;
constant MAX_PACKET_SIZE (line 89) | pub const MAX_PACKET_SIZE: u16 = 1024;
FILE: crates/trippy-tui/src/config/file.rs
constant DEFAULT_CONFIG_FILE (line 19) | const DEFAULT_CONFIG_FILE: &str = "trippy.toml";
constant DEFAULT_HIDDEN_CONFIG_FILE (line 20) | const DEFAULT_HIDDEN_CONFIG_FILE: &str = ".trippy.toml";
function read_default_config_file (line 36) | pub fn read_default_config_file() -> anyhow::Result<Option<ConfigFile>> {
function read_config_file (line 55) | pub fn read_config_file<P: AsRef<Path>>(path: P) -> anyhow::Result<Confi...
function read_files (line 64) | fn read_files<P: AsRef<Path>>(dir: P) -> anyhow::Result<Option<ConfigFil...
function read_file (line 74) | fn read_file<P: AsRef<Path>>(dir: P, file: &str) -> anyhow::Result<Optio...
type ConfigFile (line 85) | pub struct ConfigFile {
method default (line 96) | fn default() -> Self {
type ConfigTrippy (line 111) | pub struct ConfigTrippy {
method default (line 120) | fn default() -> Self {
type ConfigStrategy (line 133) | pub struct ConfigStrategy {
method default (line 168) | fn default() -> Self {
type ConfigDns (line 200) | pub struct ConfigDns {
method default (line 213) | fn default() -> Self {
type ConfigReport (line 226) | pub struct ConfigReport {
method default (line 231) | fn default() -> Self {
type ConfigTui (line 240) | pub struct ConfigTui {
method default (line 262) | fn default() -> Self {
type ConfigThemeColors (line 285) | pub struct ConfigThemeColors {
method default (line 323) | fn default() -> Self {
type ConfigBindings (line 366) | pub struct ConfigBindings {
method default (line 410) | fn default() -> Self {
function humantime_deser (line 456) | fn humantime_deser<'de, D>(deserializer: D) -> Result<Option<Duration>, ...
function addr_deser (line 465) | fn addr_deser<'de, D>(deserializer: D) -> Result<Option<IpAddr>, D::Error>
function test_parse_config_sample (line 479) | fn test_parse_config_sample() {
FILE: crates/trippy-tui/src/config/theme.rs
type TuiTheme (line 9) | pub struct TuiTheme {
method from (line 129) | fn from(value: (HashMap<TuiThemeItem, TuiColor>, ConfigThemeColors)) -...
method default (line 87) | fn default() -> Self {
type TuiThemeItem (line 276) | pub enum TuiThemeItem {
type TuiColor (line 350) | pub enum TuiColor {
type Error (line 500) | type Error = anyhow::Error;
method try_from (line 502) | fn try_from(value: String) -> Result<Self, Self::Error> {
type Error (line 508) | type Error = anyhow::Error;
method try_from (line 511) | fn try_from(value: &str) -> Result<Self, Self::Error> {
FILE: crates/trippy-tui/src/frontend.rs
function run_frontend (line 29) | pub fn run_frontend(
type ExitAction (line 64) | enum ExitAction {
function run_app (line 72) | fn run_app<B: Backend>(terminal: &mut Terminal<B>, app: &mut TuiApp) -> ...
FILE: crates/trippy-tui/src/frontend/binding.rs
type Bindings (line 8) | pub struct Bindings {
method from (line 50) | fn from(value: TuiBindings) -> Self {
type KeyBinding (line 96) | pub struct KeyBinding {
method check (line 102) | pub fn check(&self, event: KeyEvent) -> bool {
method from (line 112) | fn from(value: TuiKeyBinding) -> Self {
method fmt (line 121) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
constant CTRL_C (line 168) | pub const CTRL_C: KeyBinding = KeyBinding {
FILE: crates/trippy-tui/src/frontend/columns.rs
type Columns (line 11) | pub struct Columns(Vec<Column>);
method constraints (line 22) | pub fn constraints(&self, rect: Rect) -> Vec<Constraint> {
method columns (line 44) | pub fn columns(&self) -> impl Iterator<Item = &Column> {
method all_columns (line 50) | pub fn all_columns(&self) -> impl Iterator<Item = &Column> {
method all_columns_count (line 54) | pub fn all_columns_count(&self) -> usize {
method toggle (line 58) | pub fn toggle(&mut self, index: usize) {
method move_down (line 65) | pub fn move_down(&mut self, index: usize) {
method move_up (line 72) | pub fn move_up(&mut self, index: usize) {
method from (line 81) | fn from(value: TuiColumns) -> Self {
method fmt (line 93) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type Column (line 110) | pub struct Column {
method new_shown (line 116) | pub const fn new_shown(typ: ColumnType) -> Self {
method new_hidden (line 122) | pub const fn new_hidden(typ: ColumnType) -> Self {
method from (line 242) | fn from(value: TuiColumn) -> Self {
type ColumnStatus (line 131) | pub enum ColumnStatus {
method fmt (line 137) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type ColumnType (line 147) | pub enum ColumnType {
method name (line 284) | pub(self) fn name(&self) -> Cow<'_, str> {
method width (line 326) | pub(self) fn width(self) -> ColumnWidth {
function from (line 207) | fn from(col_type: ColumnType) -> Self {
method fmt (line 277) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type ColumnWidth (line 364) | enum ColumnWidth {
function test_columns_conversion_from_tui_columns (line 378) | fn test_columns_conversion_from_tui_columns() {
function test_column_conversion_from_tui_column (line 429) | fn test_column_conversion_from_tui_column() {
function test_column_display_formatting (line 449) | fn test_column_display_formatting(c: ColumnType, heading: &'static str) {
function test_column_width (line 457) | fn test_column_width(column_type: ColumnType, width: &ColumnWidth) {
function test_column_constraints (line 462) | fn test_column_constraints() {
function test_columns_into_string_short (line 485) | fn test_columns_into_string_short() {
function test_columns_into_string_happy_path (line 497) | fn test_columns_into_string_happy_path() {
function test_columns_into_string_reverse_str (line 516) | fn test_columns_into_string_reverse_str() {
FILE: crates/trippy-tui/src/frontend/config.rs
type TuiConfig (line 11) | pub struct TuiConfig {
method new (line 45) | pub fn new(
FILE: crates/trippy-tui/src/frontend/render/app.rs
function render (line 40) | pub fn render(f: &mut Frame<'_>, app: &mut TuiApp) {
constant LAYOUT_WITHOUT_TABS (line 75) | const LAYOUT_WITHOUT_TABS: [Constraint; 4] = [
constant LAYOUT_WITH_TABS (line 82) | const LAYOUT_WITH_TABS: [Constraint; 5] = [
constant LAYOUT_WITH_FLOWS (line 90) | const LAYOUT_WITH_FLOWS: [Constraint; 5] = [
FILE: crates/trippy-tui/src/frontend/render/bar.rs
function render (line 13) | pub fn render(f: &mut Frame<'_>, rect: Rect, app: &TuiApp) {
function fmt_privilege_mode (line 111) | fn fmt_privilege_mode(privilege_mode: PrivilegeMode) -> Cow<'static, str> {
function fmt_target_family (line 118) | const fn fmt_target_family(target: IpAddr) -> &'static str {
FILE: crates/trippy-tui/src/frontend/render/body.rs
function render (line 10) | pub fn render(f: &mut Frame<'_>, rec: Rect, app: &mut TuiApp) {
FILE: crates/trippy-tui/src/frontend/render/bsod.rs
function render (line 9) | pub fn render(f: &mut Frame<'_>, rect: Rect, error: &str) {
FILE: crates/trippy-tui/src/frontend/render/chart.rs
function render (line 11) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
FILE: crates/trippy-tui/src/frontend/render/flows.rs
function render (line 10) | pub fn render(f: &mut Frame<'_>, rect: Rect, app: &TuiApp) {
FILE: crates/trippy-tui/src/frontend/render/footer.rs
function render (line 9) | pub fn render(f: &mut Frame<'_>, rec: Rect, app: &TuiApp) {
FILE: crates/trippy-tui/src/frontend/render/header.rs
function render (line 18) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
function render_source (line 155) | fn render_source(app: &TuiApp) -> String {
function render_destination (line 197) | fn render_destination(app: &TuiApp) -> String {
function render_status (line 240) | fn render_status(app: &TuiApp) -> String {
FILE: crates/trippy-tui/src/frontend/render/help.rs
function render (line 11) | pub fn render(f: &mut Frame<'_>, app: &TuiApp) {
FILE: crates/trippy-tui/src/frontend/render/histogram.rs
function render (line 11) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
function sample_frequency (line 42) | fn sample_frequency(samples: &[Duration]) -> Vec<(String, u64)> {
FILE: crates/trippy-tui/src/frontend/render/history.rs
function render (line 9) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
FILE: crates/trippy-tui/src/frontend/render/settings.rs
function render (line 18) | pub fn render(f: &mut Frame<'_>, app: &mut TuiApp) {
function render_settings_tabs (line 33) | fn render_settings_tabs(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
function render_settings_table (line 59) | fn render_settings_table(
function render_settings_info (line 107) | fn render_settings_info(f: &mut Frame<'_>, app: &TuiApp, rect: Rect, inf...
function format_all_settings (line 124) | fn format_all_settings(app: &TuiApp) -> Vec<(String, String, Vec<Setting...
function format_tui_settings (line 180) | fn format_tui_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_trace_settings (line 229) | fn format_trace_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_dns_settings (line 295) | fn format_dns_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_geoip_settings (line 321) | fn format_geoip_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_binding_settings (line 332) | fn format_binding_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_theme_settings (line 411) | fn format_theme_settings(app: &TuiApp) -> Vec<SettingsItem> {
function format_columns_settings (line 523) | fn format_columns_settings(app: &TuiApp) -> Vec<SettingsItem> {
constant SETTINGS_TAB_COLUMNS (line 532) | pub const SETTINGS_TAB_COLUMNS: usize = 6;
function settings_tabs (line 535) | pub fn settings_tabs() -> [(String, usize); 7] {
function settings_table_header (line 548) | pub fn settings_table_header() -> [String; 2] {
constant SETTINGS_TABLE_WIDTH (line 555) | const SETTINGS_TABLE_WIDTH: [Constraint; 3] = [
type SettingsItem (line 561) | struct SettingsItem {
method new (line 567) | pub fn new(item: impl Into<String>, value: String) -> Self {
function format_dns_method (line 576) | fn format_dns_method(resolve_method: ResolveMethod) -> String {
function format_extension_mode (line 585) | fn format_extension_mode(icmp_extension_mode: IcmpExtensionMode) -> Stri...
function format_as_mode (line 595) | fn format_as_mode(as_mode: AsMode) -> String {
function format_address_mode (line 607) | fn format_address_mode(address_mode: AddressMode) -> String {
function format_geoip_mode (line 616) | fn format_geoip_mode(geoip_mode: GeoIpMode) -> String {
FILE: crates/trippy-tui/src/frontend/render/splash.rs
function render (line 13) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
FILE: crates/trippy-tui/src/frontend/render/table.rs
function render (line 45) | pub fn render(f: &mut Frame<'_>, app: &mut TuiApp, rect: Rect) {
function render_table_header (line 84) | fn render_table_header(theme: Theme, table_columns: &Columns) -> Row<'st...
function render_table_row (line 95) | fn render_table_row(
function new_cell (line 136) | fn new_cell(
function render_usize_cell (line 186) | fn render_usize_cell(value: usize) -> Cell<'static> {
function render_nat_cell (line 190) | fn render_nat_cell(value: NatStatus) -> Cell<'static> {
function render_pct_cell (line 198) | fn render_pct_cell(value: f64) -> Cell<'static> {
function render_avg_cell (line 202) | fn render_avg_cell(hop: &Hop) -> Cell<'static> {
function render_stddev_cell (line 210) | fn render_stddev_cell(hop: &Hop) -> Cell<'static> {
function render_float_cell (line 218) | fn render_float_cell(value: Option<f64>, places: usize, total_recv: usiz...
function render_status_cell (line 226) | fn render_status_cell(hop: &Hop, is_target: bool) -> Cell<'static> {
function render_icmp_packet_type_cell (line 237) | fn render_icmp_packet_type_cell(icmp_packet_type: Option<IcmpPacketType>...
function render_icmp_packet_code_cell (line 247) | fn render_icmp_packet_code_cell(icmp_packet_type: Option<IcmpPacketType>...
function render_port_cell (line 258) | fn render_port_cell(port: u16) -> Cell<'static> {
function render_dscp_cell (line 266) | fn render_dscp_cell(dscp: Option<Dscp>) -> Cell<'static> {
function render_ecn_cell (line 296) | fn render_ecn_cell(ecn: Option<Ecn>) -> Cell<'static> {
function render_asn_cell (line 306) | fn render_asn_cell(hop: &Hop, dns: &DnsResolver, config: &TuiConfig) -> ...
function render_hostname (line 324) | fn render_hostname(
function visible_addresses (line 350) | fn visible_addresses(hop: &Hop, max_addrs: Option<u8>) -> (Vec<(&IpAddr,...
function format_address (line 371) | fn format_address(
function format_dns_entry (line 446) | fn format_dns_entry(dns_entry: DnsEntry, lookup_as_info: bool, as_mode: ...
function format_asinfo (line 470) | fn format_asinfo(asinfo: &AsInfo, as_mode: AsMode) -> String {
function format_asinfo_cell (line 481) | fn format_asinfo_cell(addr: IpAddr, dns: &DnsResolver) -> String {
function format_extensions (line 496) | fn format_extensions(config: &TuiConfig, hop: &Hop) -> Option<String> {
function format_extensions_mpls (line 512) | fn format_extensions_mpls(extensions: &Extensions) -> Option<String> {
function format_extensions_full (line 534) | fn format_extensions_full(extensions: &Extensions) -> Option<String> {
function format_extensions_all (line 556) | fn format_extensions_all(extensions: &Extensions) -> String {
function format_ext_mpls_stack_member (line 573) | pub fn format_ext_mpls_stack_member(member: &MplsLabelStackMember) -> St...
function format_ext_unknown (line 581) | pub fn format_ext_unknown(unknown: &UnknownExtension) -> String {
function render_hostname_with_details (line 591) | fn render_hostname_with_details(
function format_details (line 612) | fn format_details(
function fmt_details_line (line 703) | fn fmt_details_line(
FILE: crates/trippy-tui/src/frontend/render/tabs.rs
function render (line 10) | pub fn render(f: &mut Frame<'_>, rect: Rect, app: &TuiApp) {
FILE: crates/trippy-tui/src/frontend/render/util.rs
function centered_rect (line 3) | pub fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect {
FILE: crates/trippy-tui/src/frontend/render/world.rs
function render (line 16) | pub fn render(f: &mut Frame<'_>, app: &TuiApp, rect: Rect) {
function render_map_canvas (line 31) | fn render_map_canvas(f: &mut Frame<'_>, app: &TuiApp, rect: Rect, entrie...
function render_map_canvas_world (line 74) | fn render_map_canvas_world(ctx: &mut Context<'_>, color: Color) {
function render_map_canvas_pin (line 82) | fn render_map_canvas_pin(ctx: &mut Context<'_>, entry: &MapEntry) {
function render_map_canvas_radius (line 92) | fn render_map_canvas_radius(ctx: &mut Context<'_>, entry: &MapEntry, col...
function render_map_canvas_selected (line 112) | fn render_map_canvas_selected(
function render_map_info_panel (line 136) | fn render_map_info_panel(f: &mut Frame<'_>, app: &TuiApp, rect: Rect, en...
type MapEntry (line 188) | struct MapEntry {
function build_map_entries (line 200) | fn build_map_entries(app: &TuiApp) -> Vec<MapEntry> {
constant MAP_LAYOUT (line 222) | const MAP_LAYOUT: [Constraint; 3] = [
FILE: crates/trippy-tui/src/frontend/theme.rs
type Theme (line 6) | pub struct Theme {
method from (line 84) | fn from(value: TuiTheme) -> Self {
method from (line 126) | fn from(value: TuiColor) -> Self {
function fmt_color (line 276) | pub fn fmt_color(color: Color) -> String {
FILE: crates/trippy-tui/src/frontend/tui_app.rs
type TuiApp (line 13) | pub struct TuiApp {
method new (line 48) | pub fn new(
method tracer_data (line 78) | pub const fn tracer_data(&self) -> &State {
method snapshot_trace_data (line 82) | pub fn snapshot_trace_data(&mut self) {
method clear_trace_data (line 86) | pub fn clear_trace_data(&self) {
method selected_hop_or_target (line 90) | pub fn selected_hop_or_target(&self) -> &Hop {
method selected_hop (line 97) | pub fn selected_hop(&self) -> Option<&Hop> {
method tracer_config (line 103) | pub fn tracer_config(&self) -> &TraceInfo {
method clamp_selected_hop (line 107) | pub fn clamp_selected_hop(&mut self) {
method update_order_flow_counts (line 116) | pub fn update_order_flow_counts(&mut self) {
method next_hop (line 140) | pub fn next_hop(&mut self) {
method previous_hop (line 160) | pub fn previous_hop(&mut self) {
method next_trace (line 179) | pub fn next_trace(&mut self) {
method previous_trace (line 186) | pub fn previous_trace(&mut self) {
method next_hop_address (line 193) | pub fn next_hop_address(&mut self) {
method previous_hop_address (line 201) | pub fn previous_hop_address(&mut self) {
method flow_count (line 207) | pub fn flow_count(&self) -> usize {
method next_flow (line 211) | pub fn next_flow(&mut self) {
method previous_flow (line 224) | pub fn previous_flow(&mut self) {
method next_settings_tab (line 237) | pub fn next_settings_tab(&mut self) {
method previous_settings_tab (line 244) | pub fn previous_settings_tab(&mut self) {
method next_settings_item (line 251) | pub fn next_settings_item(&mut self) {
method previous_settings_item (line 267) | pub fn previous_settings_item(&mut self) {
method get_settings_items_count (line 282) | fn get_settings_items_count(&self) -> usize {
method toggle_column_visibility (line 290) | pub fn toggle_column_visibility(&mut self) {
method move_column_down (line 298) | pub fn move_column_down(&mut self) {
method move_column_up (line 310) | pub fn move_column_up(&mut self) {
method clear (line 321) | pub fn clear(&mut self) {
method toggle_help (line 326) | pub fn toggle_help(&mut self) {
method toggle_settings (line 330) | pub fn toggle_settings(&mut self) {
method show_settings_columns (line 334) | pub fn show_settings_columns(&mut self, column_index: usize) {
method toggle_hop_details (line 342) | pub fn toggle_hop_details(&mut self) {
method toggle_freeze (line 351) | pub fn toggle_freeze(&mut self) {
method toggle_chart (line 358) | pub fn toggle_chart(&mut self) {
method toggle_map (line 363) | pub fn toggle_map(&mut self) {
method toggle_flows (line 368) | pub fn toggle_flows(&mut self) {
method expand_privacy (line 382) | pub fn expand_privacy(&mut self) {
method contract_privacy (line 393) | pub fn contract_privacy(&mut self) {
method toggle_asinfo (line 403) | pub fn toggle_asinfo(&mut self) {
method expand_hosts (line 413) | pub fn expand_hosts(&mut self) {
method contract_hosts (line 421) | pub fn contract_hosts(&mut self) {
method zoom_in (line 428) | pub fn zoom_in(&mut self) {
method zoom_out (line 434) | pub fn zoom_out(&mut self) {
method expand_hosts_max (line 440) | pub fn expand_hosts_max(&mut self) {
method contract_hosts_min (line 444) | pub fn contract_hosts_min(&mut self) {
method max_hosts (line 449) | pub fn max_hosts(&self) -> Option<u8> {
constant MAX_ZOOM_FACTOR (line 459) | const MAX_ZOOM_FACTOR: usize = 16;
FILE: crates/trippy-tui/src/geoip.rs
type GeoIpCity (line 12) | pub struct GeoIpCity {
method short_name (line 25) | pub fn short_name(&self) -> String {
method long_name (line 36) | pub fn long_name(&self) -> String {
method location (line 48) | pub fn location(&self) -> String {
method coordinates (line 57) | pub const fn coordinates(&self) -> Option<(f64, f64, u16)> {
method from (line 198) | fn from(value: ipinfo::IpInfoGeoIp) -> Self {
method from (line 214) | fn from((value, locale): (maxminddb::geoip2::City<'_>, &str)) -> Self {
type IpInfoGeoIp (line 80) | pub struct IpInfoGeoIp {
function test_empty (line 124) | fn test_empty() {
function test_country_asn_db_format (line 139) | fn test_country_asn_db_format() {
function test_extended_db_format (line 166) | fn test_extended_db_format() {
constant FALLBACK_LOCALE (line 256) | const FALLBACK_LOCALE: &str = "en";
type Cache (line 259) | type Cache = RefCell<HashMap<IpAddr, Option<Rc<GeoIpCity>>>>;
type GeoIpLookup (line 263) | pub struct GeoIpLookup {
method from_file (line 271) | pub fn from_file<P: AsRef<Path>>(path: P, locale: String) -> anyhow::R...
method empty (line 282) | pub fn empty() -> Self {
method lookup (line 293) | pub fn lookup(&self, addr: IpAddr) -> anyhow::Result<Option<Rc<GeoIpCi...
function localized_name (line 317) | fn localized_name(names: &maxminddb::geoip2::Names<'_>, locale: &str) ->...
function lookup_locale (line 328) | fn lookup_locale<'a>(names: &maxminddb::geoip2::Names<'a>, code: &str) -...
FILE: crates/trippy-tui/src/lib.rs
function trippy (line 24) | pub fn trippy() -> anyhow::Result<()> {
FILE: crates/trippy-tui/src/locale.rs
constant FALLBACK_LOCALE (line 9) | const FALLBACK_LOCALE: &str = "en";
function set_locale (line 17) | pub fn set_locale(locale: Option<&str>) -> String {
function available_locales (line 24) | pub fn available_locales() -> Vec<&'static str> {
function __translate (line 65) | pub fn __translate(item: &str) -> &str {
function translate_locale (line 76) | fn translate_locale<'a>(item: &'a str, locale: &str) -> &'a str {
function data (line 91) | fn data() -> &'static Data {
type Data (line 100) | struct Data(HashMap<String, Item>);
type Item (line 104) | struct Item(HashMap<String, String>);
function calculate_locale (line 107) | fn calculate_locale(cfg_locale: Option<&str>, sys_locale: Option<&str>) ...
function store_locale (line 129) | fn store_locale(new_locale: &str) {
function test_set_locale (line 160) | fn test_set_locale(cfg_locale: Option<&str>, sys_locale: Option<&str>, e...
function test_available_languages (line 165) | fn test_available_languages() {
function test_data_deserialize (line 175) | fn test_data_deserialize() {
function test_translate (line 180) | fn test_translate() {
function test_translate_macro (line 189) | fn test_translate_macro() {
function test_zh_tw_translations (line 196) | fn test_zh_tw_translations() {
FILE: crates/trippy-tui/src/print.rs
function print_tui_theme_items (line 8) | pub fn print_tui_theme_items() {
function print_tui_binding_commands (line 13) | pub fn print_tui_binding_commands() {
function print_config_template (line 18) | pub fn print_config_template() {
function print_shell_completions (line 23) | pub fn print_shell_completions(shell: Shell) -> anyhow::Result<()> {
function print_man_page (line 28) | pub fn print_man_page() -> anyhow::Result<()> {
function print_locales (line 33) | pub fn print_locales() {
function tui_theme_items (line 38) | fn tui_theme_items() -> String {
function tui_binding_commands (line 45) | fn tui_binding_commands() -> String {
function shell_completions (line 52) | fn shell_completions(shell: Shell) -> anyhow::Result<String> {
function man_page (line 60) | fn man_page() -> anyhow::Result<String> {
function test_output (line 81) | fn test_output(actual: &str, name: &str) {
FILE: crates/trippy-tui/src/report.rs
function wait_for_round (line 15) | fn wait_for_round(trace_data: &Tracer, report_cycles: usize) -> anyhow::...
FILE: crates/trippy-tui/src/report/csv.rs
function report (line 11) | pub fn report<R: Resolver>(
type CsvRow (line 31) | pub struct CsvRow {
method new (line 64) | fn new<R: Resolver>(
FILE: crates/trippy-tui/src/report/dot.rs
function report (line 11) | pub fn report(info: &TraceInfo, report_cycles: usize) -> anyhow::Result<...
FILE: crates/trippy-tui/src/report/flows.rs
function report (line 6) | pub fn report(info: &TraceInfo, report_cycles: usize) -> anyhow::Result<...
FILE: crates/trippy-tui/src/report/json.rs
function report (line 8) | pub fn report<R: Resolver>(
FILE: crates/trippy-tui/src/report/silent.rs
function report (line 6) | pub fn report(info: &TraceInfo, report_cycles: usize) -> anyhow::Result<...
FILE: crates/trippy-tui/src/report/stream.rs
function report (line 10) | pub fn report<R: Resolver>(info: &TraceInfo, resolver: &R) -> anyhow::Re...
FILE: crates/trippy-tui/src/report/table.rs
function report_md (line 10) | pub fn report_md<R: Resolver>(
function report_pretty (line 20) | pub fn report_pretty<R: Resolver>(
function run_report_table (line 28) | fn run_report_table<R: Resolver>(
FILE: crates/trippy-tui/src/report/types.rs
type Report (line 10) | pub struct Report {
type Info (line 16) | pub struct Info {
type Hop (line 23) | pub struct Hop {
method from (line 54) | fn from((value, resolver): (&trippy_core::Hop, &R)) -> Self {
type Hosts (line 84) | pub struct Hosts(pub Vec<Host>);
method from (line 87) | fn from((value, resolver): (I, &R)) -> Self {
method fmt (line 100) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type Host (line 106) | pub struct Host {
method fmt (line 112) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type Extensions (line 119) | pub struct Extensions {
method from (line 124) | fn from(value: &trippy_core::Extensions) -> Self {
method fmt (line 137) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type Extension (line 143) | pub enum Extension {
method from (line 151) | fn from(value: trippy_core::Extension) -> Self {
method fmt (line 162) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type MplsLabelStack (line 171) | pub struct MplsLabelStack {
method from (line 176) | fn from(value: trippy_core::MplsLabelStack) -> Self {
method fmt (line 188) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type MplsLabelStackMember (line 194) | pub struct MplsLabelStackMember {
method from (line 202) | fn from(value: trippy_core::MplsLabelStackMember) -> Self {
method fmt (line 213) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
type UnknownExtension (line 219) | pub struct UnknownExtension {
method from (line 226) | fn from(value: trippy_core::UnknownExtension) -> Self {
method fmt (line 236) | fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
function fixed_width (line 248) | pub fn fixed_width<S>(val: &f64, serializer: S) -> Result<S::Ok, S::Error>
FILE: crates/trippy-tui/src/util.rs
function insta (line 2) | pub fn insta<F: FnOnce()>(name: &str, f: F) {
function remove_whitespace (line 11) | pub fn remove_whitespace(mut s: String) -> String {
FILE: crates/trippy/src/main.rs
function main (line 1) | fn main() -> anyhow::Result<()> {
FILE: examples/hello-world/src/main.rs
function main (line 4) | fn main() -> anyhow::Result<()> {
FILE: examples/toy-traceroute/src/main.rs
type Args (line 15) | struct Args {
function main (line 37) | fn main() -> anyhow::Result<()> {
Condensed preview — 257 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,802K chars).
[
{
"path": ".config/spellcheck.toml",
"chars": 166,
"preview": "dev_comments = true\nskip_readme = false\n\n[Hunspell]\nlang = \"en_US\"\nsearch_dirs = [\".\"]\nextra_dictionaries = [\"trippy.dic"
},
{
"path": ".config/trippy.dic",
"chars": 770,
"preview": "100\n%\n'\n+\n100ms\n10ms\n1s\n300s\n5s\n=\n>\nASN\nBSD4\nCSV\nCloudflare\nDF\nDSCP\nECMP\nECN\nEndianness\nFreeBSD\nGeoIp\nGeolocation\nGraphv"
},
{
"path": ".devcontainer/devcontainer.json",
"chars": 124,
"preview": "{\n\t\"image\": \"mcr.microsoft.com/devcontainers/universal:2\",\n\t\"features\": {\n\t\t\"ghcr.io/devcontainers/features/rust:1\": {}\n"
},
{
"path": ".github/FUNDING.yml",
"chars": 50,
"preview": "github: fujiapple852\nbuy_me_a_coffee: fujiapple852"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 920,
"preview": "---\nname: Bug report\nabout: Create a bug report\ntitle: ''\nlabels: triage\nassignees: ''\n---\n\n**Describe the bug**\n\n<!-- A"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 466,
"preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: triage\nassignees: ''\n---\n\n**Describe"
},
{
"path": ".github/dependabot.yml",
"chars": 647,
"preview": "version: 2\nupdates:\n - package-ecosystem: \"cargo\"\n directory: \"/\"\n schedule:\n interval: \"daily\"\n ignore:\n"
},
{
"path": ".github/workflows/ci.yml",
"chars": 8253,
"preview": "on:\n pull_request:\n branches: [ master ]\n schedule:\n - cron: '00 18 * * *'\n\nname: CI\n\njobs:\n test:\n runs-on:"
},
{
"path": ".github/workflows/deploy.yml",
"chars": 615,
"preview": "on:\n push:\n branches: [ master ]\n\npermissions:\n contents: read\n pages: write\n id-token: write\n\njobs:\n build:\n "
},
{
"path": ".github/workflows/release.yml",
"chars": 7606,
"preview": "name: release\non:\n push:\n tags:\n - \"[0-9]+.[0-9]+.[0-9]+\"\njobs:\n create-release:\n name: create-release\n "
},
{
"path": ".gitignore",
"chars": 55,
"preview": "/target\n.idea\n.DS_Store\n.vscode/launch.json\n*.snap.new\n"
},
{
"path": "AGENTS.md",
"chars": 1580,
"preview": "# Trippy Agent Guidelines\n\nThis repository follows the guidance below when making changes.\n\n## Development commands\n\n- C"
},
{
"path": "CHANGELOG.md",
"chars": 28462,
"preview": "# Changelog\n\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "CONTRIBUTING.md",
"chars": 8837,
"preview": "# Contributing to Trippy\n\nContributions to Trippy are most welcome, whether you wish to report a bug, request a feature,"
},
{
"path": "Cargo.toml",
"chars": 3304,
"preview": "[workspace]\nresolver = \"2\"\nmembers = [\n \"crates/trippy\",\n \"crates/trippy-tui\",\n \"crates/trippy-core\",\n \"crates/tripp"
},
{
"path": "Dockerfile",
"chars": 2215,
"preview": "FROM rust:1.85 AS build-env\nRUN rustup target add x86_64-unknown-linux-musl\nWORKDIR /app\nCOPY Cargo.toml /app\nCOPY Cargo"
},
{
"path": "LICENSE",
"chars": 9723,
"preview": " Apache License\n Version 2.0, January 2004\n http"
},
{
"path": "README.md",
"chars": 9253,
"preview": "<p align=\"center\">\n <img src=\"https://raw.githubusercontent.com/fujiapple852/trippy/master/docs/src/assets/Trippy-Verti"
},
{
"path": "RELEASES.md",
"chars": 89125,
"preview": "# Release Notes\n\nRelease notes for Trippy 0.6.0 onwards. See also the [CHANGELOG](CHANGELOG.md).\n\n# 0.13.0\n\n## Highlight"
},
{
"path": "crates/README.md",
"chars": 1810,
"preview": "## Crates\n\nThe following is a list of the crates defined by Trippy and their purposes:\n\n### `trippy`\n\nA binary crate for"
},
{
"path": "crates/trippy/Cargo.toml",
"chars": 1071,
"preview": "[package]\nname = \"trippy\"\ndescription = \"A network diagnostic tool\"\nversion.workspace = true\nauthors.workspace = true\ndo"
},
{
"path": "crates/trippy/src/lib.rs",
"chars": 666,
"preview": "#![allow(\n rustdoc::broken_intra_doc_links,\n rustdoc::bare_urls,\n clippy::doc_markdown,\n clippy::doc_lazy_co"
},
{
"path": "crates/trippy/src/main.rs",
"chars": 61,
"preview": "fn main() -> anyhow::Result<()> {\n trippy_tui::trippy()\n}\n"
},
{
"path": "crates/trippy-core/Cargo.toml",
"chars": 2037,
"preview": "[package]\nname = \"trippy-core\"\ndescription = \"A network tracing library\"\nversion.workspace = true\nauthors.workspace = tr"
},
{
"path": "crates/trippy-core/src/builder.rs",
"chars": 26912,
"preview": "use crate::config::{ChannelConfig, StateConfig, StrategyConfig};\nuse crate::constants::MAX_INITIAL_SEQUENCE;\nuse crate::"
},
{
"path": "crates/trippy-core/src/config.rs",
"chars": 11827,
"preview": "use crate::types::Port;\nuse crate::{\n MaxInflight, MaxRounds, PacketSize, PayloadPattern, Sequence, TimeToLive, Trace"
},
{
"path": "crates/trippy-core/src/constants.rs",
"chars": 903,
"preview": "/// The maximum time-to-live value allowed.\n///\n/// The IP `ttl` is an u8 (0..255) but since a `ttl` of zero isn't usefu"
},
{
"path": "crates/trippy-core/src/error.rs",
"chars": 4456,
"preview": "use std::fmt::{Display, Formatter};\nuse std::io;\nuse std::net::{IpAddr, SocketAddr};\nuse thiserror::Error;\n\n/// A tracer"
},
{
"path": "crates/trippy-core/src/flows.rs",
"chars": 13317,
"preview": "use derive_more::{Add, AddAssign, Sub, SubAssign};\nuse itertools::{EitherOrBoth, Itertools};\nuse std::fmt::{Debug, Displ"
},
{
"path": "crates/trippy-core/src/lib.rs",
"chars": 2738,
"preview": "//! Trippy - A network tracing library.\n//!\n//! This crate provides the core network tracing facility used by the\n//! st"
},
{
"path": "crates/trippy-core/src/net/channel.rs",
"chars": 8904,
"preview": "use crate::config::ChannelConfig;\nuse crate::error::{Error, Result};\nuse crate::net::socket::Socket;\nuse crate::net::{Ne"
},
{
"path": "crates/trippy-core/src/net/common.rs",
"chars": 2939,
"preview": "use crate::error::ErrorKind;\nuse crate::error::{Error, Result};\nuse std::net::SocketAddr;\n\n/// Utility methods to map er"
},
{
"path": "crates/trippy-core/src/net/extension.rs",
"chars": 4745,
"preview": "use crate::error::Error;\nuse crate::probe::{Extension, Extensions, MplsLabelStack, MplsLabelStackMember, UnknownExtensio"
},
{
"path": "crates/trippy-core/src/net/ipv4.rs",
"chars": 72423,
"preview": "use crate::config::IcmpExtensionParseMode;\nuse crate::error::{Error, ErrorKind, Result};\nuse crate::net::channel::MAX_PA"
},
{
"path": "crates/trippy-core/src/net/ipv6.rs",
"chars": 68393,
"preview": "use crate::config::IcmpExtensionParseMode;\nuse crate::error::{Error, ErrorKind, Result};\nuse crate::net::channel::MAX_PA"
},
{
"path": "crates/trippy-core/src/net/platform/byte_order.rs",
"chars": 2866,
"preview": "use crate::error::Result;\nuse crate::net::platform::{Platform, PlatformImpl};\nuse std::net::IpAddr;\n\n/// The byte order "
},
{
"path": "crates/trippy-core/src/net/platform/unix.rs",
"chars": 21768,
"preview": "use crate::error::Result;\nuse crate::net::platform::{Ipv4ByteOrder, Platform};\nuse std::net::IpAddr;\n\npub struct Platfor"
},
{
"path": "crates/trippy-core/src/net/platform/windows.rs",
"chars": 32062,
"preview": "use super::byte_order::Ipv4ByteOrder;\nuse crate::error::{Error, ErrorKind, IoError, IoOperation, IoResult, Result};\nuse "
},
{
"path": "crates/trippy-core/src/net/platform.rs",
"chars": 857,
"preview": "pub mod byte_order;\n\npub use byte_order::Ipv4ByteOrder;\nuse std::net::IpAddr;\n\n#[cfg(unix)]\nmod unix;\n\nuse crate::error:"
},
{
"path": "crates/trippy-core/src/net/socket.rs",
"chars": 3393,
"preview": "use crate::error::IoResult as Result;\nuse std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};\nuse std::time::Duration;\n\n"
},
{
"path": "crates/trippy-core/src/net/source.rs",
"chars": 7082,
"preview": "use crate::PortDirection;\nuse crate::error::Error::InvalidSourceAddr;\nuse crate::error::Result;\nuse crate::net::platform"
},
{
"path": "crates/trippy-core/src/net.rs",
"chars": 944,
"preview": "use crate::error::Result;\nuse crate::probe::{Probe, Response};\n\n/// Common types and helper functions.\nmod common;\n\n/// "
},
{
"path": "crates/trippy-core/src/probe.rs",
"chars": 13961,
"preview": "use crate::TypeOfService;\nuse crate::types::{Checksum, Flags, Port, RoundId, Sequence, TimeToLive, TraceId};\nuse std::ne"
},
{
"path": "crates/trippy-core/src/state.rs",
"chars": 41580,
"preview": "use crate::config::StateConfig;\nuse crate::constants::MAX_TTL;\nuse crate::flows::{Flow, FlowId, FlowRegistry};\nuse crate"
},
{
"path": "crates/trippy-core/src/strategy.rs",
"chars": 67015,
"preview": "use self::state::TracerState;\nuse crate::config::StrategyConfig;\nuse crate::error::{Error, Result};\nuse crate::net::Netw"
},
{
"path": "crates/trippy-core/src/tracer.rs",
"chars": 23191,
"preview": "use crate::error::Result;\nuse crate::{\n Error, IcmpExtensionParseMode, MaxInflight, MaxRounds, MultipathStrategy, Pac"
},
{
"path": "crates/trippy-core/src/types.rs",
"chars": 6447,
"preview": "use bitflags::bitflags;\nuse derive_more::{Add, AddAssign, Rem, Sub};\nuse std::num::NonZeroUsize;\n\n/// `Round` newtype.\n#"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp.toml",
"chars": 653,
"preview": "name = \"IPv4/ICMP\"\ntarget = \"10.0.0.107\"\nprotocol = \"Icmp\"\nicmp_identifier = 1\n\n[[hops]]\nttl = 1\nresp = { tag = \"SingleH"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_gaps.toml",
"chars": 776,
"preview": "name = \"IPv4/ICMP with 9 hops, 2 of which do not respond\"\ntarget = \"10.0.0.109\"\nprotocol = \"Icmp\"\nicmp_identifier = 3\n\n["
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_min.toml",
"chars": 369,
"preview": "name = \"IPv4/ICMP with a minimum packet size\"\ntarget = \"10.0.0.103\"\nprotocol = \"Icmp\"\nicmp_identifier = 5\npacket_size = "
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_ooo.toml",
"chars": 536,
"preview": "name = \"IPv4/ICMP with out of order responses\"\ntarget = \"10.0.0.105\"\nprotocol = \"Icmp\"\nicmp_identifier = 4\ngrace_duratio"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_pattern.toml",
"chars": 390,
"preview": "name = \"IPv4/ICMP with an alternative payload pattern (0xFF)\"\ntarget = \"10.0.0.103\"\nprotocol = \"Icmp\"\nicmp_identifier = "
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_quick.toml",
"chars": 1010,
"preview": "name = \"IPv4/ICMP with min/max round duration 250ms and grace 50ms\"\ntarget = \"10.0.0.110\"\nprotocol = \"Icmp\"\nicmp_identif"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_tos.toml",
"chars": 346,
"preview": "name = \"IPv4/ICMP with a TOS\"\ntarget = \"10.0.0.103\"\nprotocol = \"Icmp\"\nicmp_identifier = 9\ntos = 224\n\n[[hops]]\nttl = 1\nre"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_icmp_wrap.toml",
"chars": 2581,
"preview": "name = \"IPv4/ICMP wrap sequence\"\ntarget = \"10.0.0.130\"\nrounds = 20\nprotocol = \"Icmp\"\nicmp_identifier = 8\ninitial_sequenc"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_tcp_fixed_dest.toml",
"chars": 387,
"preview": "name = \"IPv4/TCP with a fixed dest port\"\ntarget = \"10.0.0.103\"\nprotocol = \"Tcp\"\nport_direction = { tag = \"FixedDest\", va"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_classic_fixed_dest.toml",
"chars": 419,
"preview": "name = \"IPv4/UDP classic with a fixed dest port\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nport_direction = { tag = \"FixedD"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_classic_fixed_src.toml",
"chars": 416,
"preview": "name = \"IPv4/UDP classic with a fixed src port\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nport_direction = { tag = \"FixedSr"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_classic_privileged_tos.toml",
"chars": 428,
"preview": "name = \"IPv4/UDP classic privileged with a TOS\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nport_direction = { tag = \"FixedDe"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_classic_unprivileged.toml",
"chars": 441,
"preview": "name = \"IPv4/UDP classic unprivileged\"\nprivilege_mode = \"Unprivileged\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nport_direc"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_classic_unprivileged_tos.toml",
"chars": 462,
"preview": "name = \"IPv4/UDP classic unprivileged with a TOS\"\nprivilege_mode = \"Unprivileged\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\""
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_dublin_fixed_both.toml",
"chars": 448,
"preview": "name = \"IPv4/UDP Dublin with a fixed src and dest port\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nmultipath_strategy = \"Dub"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv4_udp_paris_fixed_both.toml",
"chars": 446,
"preview": "name = \"IPv4/UDP Paris with a fixed src and dest port\"\ntarget = \"10.0.0.103\"\nprotocol = \"Udp\"\nmultipath_strategy = \"Pari"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_icmp.toml",
"chars": 669,
"preview": "name = \"IPv6/ICMP\"\ntarget = \"fd00:10::107\"\nprotocol = \"Icmp\"\nicmp_identifier = 1\n\n[[hops]]\nttl = 1\nresp = { tag = \"Singl"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_icmp_min.toml",
"chars": 377,
"preview": "name = \"IPv6/ICMP with a minimum packet size\"\ntarget = \"fd00:10::103\"\nprotocol = \"Icmp\"\nicmp_identifier = 5\npacket_size "
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_icmp_pattern.toml",
"chars": 398,
"preview": "name = \"IPv6/ICMP with an alternative payload pattern (0xFF)\"\ntarget = \"fd00:10::103\"\nprotocol = \"Icmp\"\nicmp_identifier "
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_tcp_fixed_dest.toml",
"chars": 385,
"preview": "name = \"IPv6/TCP with a fixed dest port\"\ntarget = \"fd00:10::103\"\nprotocol = \"Tcp\"\nport_direction = { tag = \"FixedDest\", "
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_classic_fixed_dest.toml",
"chars": 427,
"preview": "name = \"IPv6/UDP classic with a fixed dest port\"\ntarget = \"fd00:10::103\"\nprotocol = \"Udp\"\nport_direction = { tag = \"Fixe"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_classic_fixed_src.toml",
"chars": 424,
"preview": "name = \"IPv6/UDP classic with a fixed src port\"\ntarget = \"fd00:10::103\"\nprotocol = \"Udp\"\nport_direction = { tag = \"Fixed"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_classic_unprivileged.toml",
"chars": 449,
"preview": "name = \"IPv6/UDP classic unprivileged\"\nprivilege_mode = \"Unprivileged\"\ntarget = \"fd00:10::103\"\nprotocol = \"Udp\"\nport_dir"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_classic_unprivileged_tos.toml",
"chars": 470,
"preview": "name = \"IPv6/UDP classic unprivileged with a TOS\"\nprivilege_mode = \"Unprivileged\"\ntarget = \"fd00:10::103\"\nprotocol = \"Ud"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_dublin_fixed_both.toml",
"chars": 456,
"preview": "name = \"IPv6/UDP Dublin with a fixed src and dest port\"\ntarget = \"fd00:10::103\"\nprotocol = \"Udp\"\nmultipath_strategy = \"D"
},
{
"path": "crates/trippy-core/tests/resources/simulation/ipv6_udp_paris_fixed_both.toml",
"chars": 454,
"preview": "name = \"IPv6/UDP Paris with a fixed src and dest port\"\ntarget = \"fd00:10::103\"\nprotocol = \"Udp\"\nmultipath_strategy = \"Pa"
},
{
"path": "crates/trippy-core/tests/resources/state/all_status.toml",
"chars": 534,
"preview": "largest_ttl = 1\n\n[[rounds]]\nprobes = [\n \"1 A 300 10.1.0.2 0 12340 80 0 0 0\",\n]\n\n[[rounds]]\nprobes = [\n \"1 C 700 10.1.0"
},
{
"path": "crates/trippy-core/tests/resources/state/floss_bloss.toml",
"chars": 754,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 333 10.1.0.1 0 12340 80 0 0 0\",\n \"2 C 777 10.1.0.2 1 12340 80 0 0 0\",\n \""
},
{
"path": "crates/trippy-core/tests/resources/state/full_completed.toml",
"chars": 1463,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 333 10.1.0.1 0 12340 80 0 0 0\",\n \"2 C 777 10.1.0.2 1 12340 80 0 0 0\",\n \""
},
{
"path": "crates/trippy-core/tests/resources/state/full_mixed.toml",
"chars": 1126,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 10 10.0.0.1 0 12345 80 0 0 0\",\n \"2 A 12 10.0.0.2 1 12345 80 0 0 0\",\n \"3 "
},
{
"path": "crates/trippy-core/tests/resources/state/minimal.toml",
"chars": 239,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 333 10.1.0.1 0 12340 80 0 0 0\",\n \"2 C 777 10.1.0.2 1 12340 80 0 0 0\",\n \""
},
{
"path": "crates/trippy-core/tests/resources/state/nat.toml",
"chars": 673,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 333 10.1.0.1 0 12340 80 43012 43012 0\",\n \"2 C 777 10.1.0.2 1 12340 80 205"
},
{
"path": "crates/trippy-core/tests/resources/state/no_latency.toml",
"chars": 394,
"preview": "largest_ttl = 1\n\n[[rounds]]\nprobes = [\"1 C 0 127.0.0.1 0 80 80 0 0 0\"]\n\n[[rounds]]\nprobes = [\"1 C 0 127.0.0.1 0 80 80 0 "
},
{
"path": "crates/trippy-core/tests/resources/state/non_default_minimum_ttl.toml",
"chars": 327,
"preview": "largest_ttl = 5\n\n[[rounds]]\nprobes = [\n \"4 A 333 10.1.0.1 0 12340 80 0 0 0\",\n \"5 A 777 10.1.0.2 1 12340 80 0 0 0\",\n]\n\n"
},
{
"path": "crates/trippy-core/tests/resources/state/tos.toml",
"chars": 185,
"preview": "largest_ttl = 3\n\n[[rounds]]\nprobes = [\n \"1 C 333 10.1.0.1 0 12340 80 0 0 224\",\n \"2 A 777 10.1.0.2 1 12340 80 0 0 0\",\n]"
},
{
"path": "crates/trippy-core/tests/sim/main.rs",
"chars": 184,
"preview": "#![cfg(all(\n feature = \"sim-tests\",\n any(target_os = \"linux\", target_os = \"macos\", target_os = \"windows\")\n))]\nmod "
},
{
"path": "crates/trippy-core/tests/sim/network/ipv4.rs",
"chars": 8925,
"preview": "use crate::simulation::{Protocol, Response, Simulation, SingleHost};\nuse std::net::{IpAddr, Ipv4Addr};\nuse tracing::{deb"
},
{
"path": "crates/trippy-core/tests/sim/network/ipv6.rs",
"chars": 9458,
"preview": "use crate::simulation::{Protocol, Response, Simulation, SingleHost};\nuse std::net::{IpAddr, Ipv6Addr};\nuse tracing::{deb"
},
{
"path": "crates/trippy-core/tests/sim/network.rs",
"chars": 4301,
"preview": "mod ipv4;\nmod ipv6;\n\nuse crate::simulation::Simulation;\nuse crate::tun_device::TunDevice;\nuse futures_concurrency::futur"
},
{
"path": "crates/trippy-core/tests/sim/simulation.rs",
"chars": 3809,
"preview": "use serde::Deserialize;\nuse std::net::IpAddr;\nuse trippy_core::Port;\n\n/// A simulated trace.\n#[derive(Debug, Deserialize"
},
{
"path": "crates/trippy-core/tests/sim/tests.rs",
"chars": 3865,
"preview": "use crate::simulation::Simulation;\nuse crate::tun_device::tun;\nuse crate::{network, tracer};\nuse std::sync::{Arc, Mutex,"
},
{
"path": "crates/trippy-core/tests/sim/tracer.rs",
"chars": 6322,
"preview": "use crate::simulation::{Response, Simulation, SingleHost};\nuse crate::tun_device::{TUN_NETWORK_ADDR_V4, TUN_NETWORK_ADDR"
},
{
"path": "crates/trippy-core/tests/sim/tun_device.rs",
"chars": 1817,
"preview": "use std::net::{Ipv4Addr, Ipv6Addr};\nuse std::sync::{Arc, OnceLock};\nuse tokio::sync::Mutex;\n\nstatic TUN: OnceLock<Arc<Mu"
},
{
"path": "crates/trippy-dns/Cargo.toml",
"chars": 597,
"preview": "[package]\nname = \"trippy-dns\"\ndescription = \"A lazy DNS resolver for Trippy\"\nversion.workspace = true\nauthors.workspace "
},
{
"path": "crates/trippy-dns/src/config.rs",
"chars": 2917,
"preview": "use crate::{IpAddrFamily, ResolveMethod};\nuse std::time::Duration;\n\n/// A builder for DNS `Config`.\n///\n/// # Example\n//"
},
{
"path": "crates/trippy-dns/src/lazy_resolver.rs",
"chars": 20901,
"preview": "use crate::config::Config;\nuse crate::resolver::{DnsEntry, ResolvedIpAddrs, Resolver, Result};\nuse std::fmt::{Display, F"
},
{
"path": "crates/trippy-dns/src/lib.rs",
"chars": 2877,
"preview": "//! This crate provides a cheaply cloneable, non-blocking, caching, forward\n//! and reverse DNS resolver which support t"
},
{
"path": "crates/trippy-dns/src/resolver.rs",
"chars": 6546,
"preview": "use std::fmt::{Display, Formatter};\nuse std::net::IpAddr;\nuse thiserror::Error;\n\n/// A DNS resolver.\npub trait Resolver "
},
{
"path": "crates/trippy-packet/Cargo.toml",
"chars": 507,
"preview": "[package]\nname = \"trippy-packet\"\ndescription = \"Network packets for Trippy\"\nversion.workspace = true\nauthors.workspace ="
},
{
"path": "crates/trippy-packet/src/buffer.rs",
"chars": 3440,
"preview": "/// A byte buffer that holds a mutable or immutable byte slice.\n#[derive(Debug)]\npub enum Buffer<'a> {\n Immutable(&'a"
},
{
"path": "crates/trippy-packet/src/checksum.rs",
"chars": 8287,
"preview": "//! Checksum implementations for ICMP & UDP over IPv4 and IPV6.\n//!\n//! This code is derived from [`libpnet`] which is a"
},
{
"path": "crates/trippy-packet/src/error.rs",
"chars": 383,
"preview": "use thiserror::Error;\n\n/// A packet error result.\npub type Result<T> = std::result::Result<T, Error>;\n\n/// A packet erro"
},
{
"path": "crates/trippy-packet/src/icmp_extension.rs",
"chars": 52813,
"preview": "pub mod extension_structure {\n use crate::buffer::Buffer;\n use crate::error::{Error, Result};\n use crate::icmp_"
},
{
"path": "crates/trippy-packet/src/icmpv4.rs",
"chars": 46081,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse std::fmt::{Debug, Formatter};\n\n/// The type of ICMP pa"
},
{
"path": "crates/trippy-packet/src/icmpv6.rs",
"chars": 46111,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse std::fmt::{Debug, Formatter};\n\n/// The type of `ICMPv6"
},
{
"path": "crates/trippy-packet/src/ip.rs",
"chars": 4680,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse std::fmt::{Debug, Formatter};\n\n/// The IP packet versi"
},
{
"path": "crates/trippy-packet/src/ipv4.rs",
"chars": 17851,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse crate::{IpProtocol, fmt_payload};\nuse std::fmt::{Debug"
},
{
"path": "crates/trippy-packet/src/ipv6.rs",
"chars": 14078,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse crate::{IpProtocol, fmt_payload};\nuse std::fmt::{Debug"
},
{
"path": "crates/trippy-packet/src/lib.rs",
"chars": 3100,
"preview": "//! Packet wire format parsing and building.\n//!\n//! The following packet are supported:\n//! - `IP`\n//! - `ICMPv4`\n//! -"
},
{
"path": "crates/trippy-packet/src/tcp.rs",
"chars": 16571,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse crate::fmt_payload;\nuse std::fmt::{Debug, Formatter};\n"
},
{
"path": "crates/trippy-packet/src/udp.rs",
"chars": 7455,
"preview": "use crate::buffer::Buffer;\nuse crate::error::{Error, Result};\nuse crate::fmt_payload;\nuse std::fmt::{Debug, Formatter};\n"
},
{
"path": "crates/trippy-privilege/Cargo.toml",
"chars": 792,
"preview": "[package]\nname = \"trippy-privilege\"\ndescription = \"Discover platform privileges\"\nversion.workspace = true\nauthors.worksp"
},
{
"path": "crates/trippy-privilege/src/lib.rs",
"chars": 10274,
"preview": "//! Discover platform privileges.\n//!\n//! A cross-platform library to discover and manage platform privileges needed\n//!"
},
{
"path": "crates/trippy-tui/Cargo.toml",
"chars": 1908,
"preview": "[package]\nname = \"trippy-tui\"\ndescription = \"A network diagnostic tool\"\nversion.workspace = true\nauthors.workspace = tru"
},
{
"path": "crates/trippy-tui/build.rs",
"chars": 71,
"preview": "pub fn main() {\n println!(\"cargo:rerun-if-changed=locales.toml\");\n}\n"
},
{
"path": "crates/trippy-tui/locales.toml",
"chars": 26688,
"preview": "[trippy]\nen = \"trippy\"\nfr = \"trippy\"\ntr = \"trippy\"\nit = \"trippy\"\npt = \"trippy\"\nzh = \"trippy\"\nzh-TW = \"trippy\"\nsv = \"trip"
},
{
"path": "crates/trippy-tui/src/app.rs",
"chars": 8543,
"preview": "use crate::config::{LogFormat, LogSpanEvents, Mode, TrippyConfig};\nuse crate::frontend::TuiConfig;\nuse crate::geoip::Geo"
},
{
"path": "crates/trippy-tui/src/config/binding.rs",
"chars": 28048,
"preview": "use crate::config::file::ConfigBindings;\nuse anyhow::anyhow;\nuse crossterm::event::{KeyCode, KeyModifiers};\nuse serde::D"
},
{
"path": "crates/trippy-tui/src/config/cmd.rs",
"chars": 11996,
"preview": "use crate::config::binding::TuiCommandItem;\nuse crate::config::theme::TuiThemeItem;\nuse crate::config::{\n AddressFami"
},
{
"path": "crates/trippy-tui/src/config/columns.rs",
"chars": 9001,
"preview": "use anyhow::anyhow;\nuse itertools::Itertools;\nuse std::collections::HashSet;\nuse std::fmt::{Display, Formatter};\n\n/// Th"
},
{
"path": "crates/trippy-tui/src/config/constants.rs",
"chars": 3110,
"preview": "use crate::config::{\n AddressFamilyConfig, AddressMode, AsMode, DnsResolveMethodConfig, GeoIpMode, IcmpExtensionMode,"
},
{
"path": "crates/trippy-tui/src/config/file.rs",
"chars": 20473,
"preview": "use crate::config::binding::TuiKeyBinding;\nuse crate::config::theme::TuiColor;\nuse crate::config::{\n AddressFamilyCon"
},
{
"path": "crates/trippy-tui/src/config/theme.rs",
"chars": 26102,
"preview": "use crate::config::file::ConfigThemeColors;\nuse anyhow::anyhow;\nuse serde::Deserialize;\nuse std::collections::HashMap;\nu"
},
{
"path": "crates/trippy-tui/src/config.rs",
"chars": 113163,
"preview": "use anyhow::anyhow;\nuse clap::ValueEnum;\nuse clap_complete::Shell;\nuse file::ConfigFile;\nuse itertools::Itertools;\nuse s"
},
{
"path": "crates/trippy-tui/src/frontend/binding.rs",
"chars": 7012,
"preview": "use crate::config::{TuiBindings, TuiKeyBinding};\nuse crossterm::event::{KeyCode, KeyEvent, KeyModifiers};\nuse itertools:"
},
{
"path": "crates/trippy-tui/src/frontend/columns.rs",
"chars": 19422,
"preview": "use crate::config::{TuiColumn, TuiColumns};\nuse crate::t;\nuse ratatui::layout::{Constraint, Rect};\nuse std::borrow::Cow;"
},
{
"path": "crates/trippy-tui/src/frontend/config.rs",
"chars": 2534,
"preview": "use crate::config::{AddressMode, AsMode, GeoIpMode, TuiColumns, TuiTheme};\nuse crate::config::{IcmpExtensionMode, TuiBin"
},
{
"path": "crates/trippy-tui/src/frontend/render/app.rs",
"chars": 3443,
"preview": "use crate::frontend::render::{bar, body, flows, footer, header, help, settings, tabs};\nuse crate::frontend::tui_app::Tui"
},
{
"path": "crates/trippy-tui/src/frontend/render/bar.rs",
"chars": 3664,
"preview": "use crate::config::AddressMode;\nuse crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::lay"
},
{
"path": "crates/trippy-tui/src/frontend/render/body.rs",
"chars": 734,
"preview": "use crate::frontend::render::{bsod, chart, splash, table, world};\nuse crate::frontend::tui_app::TuiApp;\nuse ratatui::Fra"
},
{
"path": "crates/trippy-tui/src/frontend/render/bsod.rs",
"chars": 1105,
"preview": "use crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::{Alignment, Constraint, Layout, Rect};\nuse ratatui::style::{Color"
},
{
"path": "crates/trippy-tui/src/frontend/render/chart.rs",
"chars": 3441,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::{Alignment, Constraint, Rec"
},
{
"path": "crates/trippy-tui/src/frontend/render/flows.rs",
"chars": 2005,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::{Alignment, Rect};\nuse rata"
},
{
"path": "crates/trippy-tui/src/frontend/render/footer.rs",
"chars": 600,
"preview": "use crate::frontend::render::{histogram, history};\nuse crate::frontend::tui_app::TuiApp;\nuse ratatui::Frame;\nuse ratatui"
},
{
"path": "crates/trippy-tui/src/frontend/render/header.rs",
"chars": 9569,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse chrono::SecondsFormat;\nuse humantime::format_duration;\nuse ratat"
},
{
"path": "crates/trippy-tui/src/frontend/render/help.rs",
"chars": 2146,
"preview": "use crate::frontend::render::util;\nuse crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::"
},
{
"path": "crates/trippy-tui/src/frontend/render/histogram.rs",
"chars": 2181,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::Rect;\nuse ratatui::style::{"
},
{
"path": "crates/trippy-tui/src/frontend/render/history.rs",
"chars": 1662,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::Rect;\nuse ratatui::style::S"
},
{
"path": "crates/trippy-tui/src/frontend/render/settings.rs",
"chars": 22754,
"preview": "use crate::config::{AddressMode, AsMode, GeoIpMode, IcmpExtensionMode};\nuse crate::frontend::render::util;\nuse crate::fr"
},
{
"path": "crates/trippy-tui/src/frontend/render/splash.rs",
"chars": 1663,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::{Alignment, Constraint, Lay"
},
{
"path": "crates/trippy-tui/src/frontend/render/table.rs",
"chars": 26752,
"preview": "use crate::config::{AddressMode, AsMode, GeoIpMode, IcmpExtensionMode};\nuse crate::frontend::columns::{ColumnType, Colum"
},
{
"path": "crates/trippy-tui/src/frontend/render/tabs.rs",
"chars": 1276,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse ratatui::Frame;\nuse ratatui::layout::{Alignment, Rect};\nuse rata"
},
{
"path": "crates/trippy-tui/src/frontend/render/util.rs",
"chars": 855,
"preview": "use ratatui::layout::{Constraint, Direction, Layout, Rect};\n\npub fn centered_rect(percent_x: u16, percent_y: u16, r: Rec"
},
{
"path": "crates/trippy-tui/src/frontend/render/world.rs",
"chars": 7332,
"preview": "use crate::frontend::tui_app::TuiApp;\nuse crate::t;\nuse itertools::Itertools;\nuse ratatui::Frame;\nuse ratatui::layout::{"
},
{
"path": "crates/trippy-tui/src/frontend/render.rs",
"chars": 258,
"preview": "pub mod app;\npub mod bar;\npub mod body;\npub mod bsod;\npub mod chart;\npub mod flows;\npub mod footer;\npub mod header;\npub "
},
{
"path": "crates/trippy-tui/src/frontend/theme.rs",
"chars": 15846,
"preview": "use crate::config::{TuiColor, TuiTheme};\nuse ratatui::style::Color;\n\n/// Tui color theme.\n#[derive(Debug, Clone, Copy)]\n"
},
{
"path": "crates/trippy-tui/src/frontend/tui_app.rs",
"chars": 14137,
"preview": "use crate::app::TraceInfo;\nuse crate::frontend::config::TuiConfig;\nuse crate::frontend::render::settings::{SETTINGS_TAB_"
},
{
"path": "crates/trippy-tui/src/frontend.rs",
"chars": 11500,
"preview": "use crate::app::TraceInfo;\nuse crate::config::AddressMode;\nuse crate::frontend::binding::CTRL_C;\nuse crate::geoip::GeoIp"
},
{
"path": "crates/trippy-tui/src/geoip.rs",
"chars": 11977,
"preview": "use anyhow::Context;\nuse itertools::Itertools;\nuse maxminddb::Reader;\nuse std::cell::RefCell;\nuse std::collections::Hash"
},
{
"path": "crates/trippy-tui/src/lib.rs",
"chars": 1168,
"preview": "#![allow(\n clippy::struct_excessive_bools,\n clippy::cast_sign_loss,\n clippy::struct_field_names\n)]\n#![forbid(un"
},
{
"path": "crates/trippy-tui/src/locale.rs",
"chars": 7477,
"preview": "use itertools::Itertools;\nuse serde::Deserialize;\nuse std::cell::RefCell;\nuse std::collections::HashMap;\nuse std::str::F"
},
{
"path": "crates/trippy-tui/src/print.rs",
"chars": 2870,
"preview": "use crate::config::{Args, TuiCommandItem, TuiThemeItem};\nuse crate::locale::available_locales;\nuse clap::CommandFactory;"
},
{
"path": "crates/trippy-tui/src/report/csv.rs",
"chars": 3042,
"preview": "use crate::app::TraceInfo;\nuse crate::report::types::fixed_width;\nuse itertools::Itertools;\nuse serde::Serialize;\nuse st"
},
{
"path": "crates/trippy-tui/src/report/dot.rs",
"chars": 1541,
"preview": "use crate::app::TraceInfo;\nuse petgraph::dot::{Config, Dot};\nuse petgraph::graphmap::DiGraphMap;\nuse std::fmt::{Debug, F"
},
{
"path": "crates/trippy-tui/src/report/flows.rs",
"chars": 418,
"preview": "use crate::app::TraceInfo;\nuse tracing::instrument;\n\n/// Run a trace and report all flows observed.\n#[instrument(skip_al"
},
{
"path": "crates/trippy-tui/src/report/json.rs",
"chars": 976,
"preview": "use crate::app::TraceInfo;\nuse crate::report::types::{Hop, Host, Info, Report};\nuse tracing::instrument;\nuse trippy_dns:"
},
{
"path": "crates/trippy-tui/src/report/silent.rs",
"chars": 287,
"preview": "use crate::app::TraceInfo;\nuse tracing::instrument;\n\n/// Run a trace without generating any output.\n#[instrument(skip_al"
},
{
"path": "crates/trippy-tui/src/report/stream.rs",
"chars": 1380,
"preview": "use crate::app::TraceInfo;\nuse crate::report::types::Hop;\nuse anyhow::anyhow;\nuse std::thread::sleep;\nuse tracing::instr"
},
{
"path": "crates/trippy-tui/src/report/table.rs",
"chars": 2575,
"preview": "use crate::app::TraceInfo;\nuse comfy_table::presets::{ASCII_MARKDOWN, UTF8_FULL};\nuse comfy_table::{ContentArrangement, "
},
{
"path": "crates/trippy-tui/src/report/types.rs",
"chars": 6681,
"preview": "use chrono::Utc;\nuse itertools::Itertools;\nuse serde::{Serialize, Serializer};\nuse std::fmt::{Display, Formatter};\nuse s"
},
{
"path": "crates/trippy-tui/src/report.rs",
"chars": 676,
"preview": "use anyhow::anyhow;\nuse trippy_core::State;\nuse trippy_core::Tracer;\n\npub mod csv;\npub mod dot;\npub mod flows;\npub mod j"
},
{
"path": "crates/trippy-tui/src/util.rs",
"chars": 404,
"preview": "#[cfg(test)]\npub fn insta<F: FnOnce()>(name: &str, f: F) {\n let mut settings = insta::Settings::new();\n settings.s"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__config__tests__compare_snapshot@trip.snap",
"chars": 6157,
"preview": "---\nsource: crates/trippy-tui/src/config.rs\n---\nAnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__config__tests__compare_snapshot@trip_--help.snap",
"chars": 7738,
"preview": "---\nsource: crates/trippy-tui/src/config.rs\n---\nAnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__config__tests__compare_snapshot@trip_-h.snap",
"chars": 6157,
"preview": "---\nsource: crates/trippy-tui/src/config.rs\n---\nAnetworkdiagnostictoolUsage:trip[OPTIONS][TARGETS]...Arguments:[TARGETS]"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_bash_shell_completions.snap",
"chars": 6144,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\n_trip(){localicurprevoptscmdCOMPREPLY=()if[[\"${BASH_VERSINFO[0]}\"-ge4]];t"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_elvish_shell_completions.snap",
"chars": 5477,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\nusebuiltin;usestr;setedit:completion:arg-completer[trip]={|@words|fnspace"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_fish_shell_completions.snap",
"chars": 6609,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\ncomplete-ctrip-sc-lconfig-file-d'Configfile'-r-Fcomplete-ctrip-sm-lmode-d"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_man_page.snap",
"chars": 14578,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\n.ie\\n(.g.dsAq\\(aq.el.dsAq'.THtrip1\"trip0.14.0-dev\".SHNAMEtrip\\-Anetworkdi"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_powershell_shell_completions.snap",
"chars": 12731,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\nusingnamespaceSystem.Management.AutomationusingnamespaceSystem.Management"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@generate_zsh_shell_completions.snap",
"chars": 10551,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\n#compdeftripautoload-Uis-at-least_trip(){typeset-Aopt_argstypeset-a_argum"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_binding_commands_match.snap",
"chars": 703,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\nTUIbindingcommands:toggle-help,toggle-help-alt,toggle-settings,toggle-set"
},
{
"path": "crates/trippy-tui/tests/resources/snapshots/trippy_tui__print__tests__output@tui_theme_items_match.snap",
"chars": 897,
"preview": "---\nsource: crates/trippy-tui/src/print.rs\n---\nTUIthemecoloritems:bg-color,border-color,text-color,tab-text-color,hops-t"
},
{
"path": "deny.toml",
"chars": 379,
"preview": "[licenses]\nversion = 2\nallow = [\"Apache-2.0\", \"MIT\", \"Unicode-DFS-2016\", \"ISC\", \"BSD-2-Clause\", \"BSD-3-Clause\", \"WTFPL\","
},
{
"path": "docs/.gitignore",
"chars": 229,
"preview": "# build output\ndist/\n# generated types\n.astro/\n\n# dependencies\nnode_modules/\n\n# logs\nnpm-debug.log*\nyarn-debug.log*\nyarn"
},
{
"path": "docs/README.md",
"chars": 2564,
"preview": "# Starlight Starter Kit: Basics\n\n[](https"
},
{
"path": "docs/astro.config.mjs",
"chars": 2496,
"preview": "import { defineConfig } from 'astro/config';\nimport starlight from '@astrojs/starlight';\nimport starlightVersions from '"
},
{
"path": "docs/package.json",
"chars": 360,
"preview": "{\n \"name\": \"trippy\",\n \"type\": \"module\",\n \"version\": \"0.0.1\",\n \"scripts\": {\n \"dev\": \"astro dev\",\n \"start\": \"ast"
},
{
"path": "docs/public/CNAME",
"chars": 10,
"preview": "trippy.rs\n"
},
{
"path": "docs/src/content/config.ts",
"chars": 322,
"preview": "import { defineCollection } from 'astro:content';\nimport { docsSchema } from '@astrojs/starlight/schema';\nimport { docsV"
},
{
"path": "docs/src/content/docs/0.12.2/development/crates.md",
"chars": 1439,
"preview": "---\ntitle: Crates\ndescription: A reference for the Trippy crates.\nslug: 0.12.2/development/crates\n---\n\nThe following tab"
},
{
"path": "docs/src/content/docs/0.12.2/guides/faq.md",
"chars": 1082,
"preview": "---\ntitle: Frequently Asked Questions\ndescription: Frequently asked questions about Trippy.\nsidebar:\n order: 5\nslug: 0."
},
{
"path": "docs/src/content/docs/0.12.2/guides/privileges.md",
"chars": 1976,
"preview": "---\ntitle: Privileges\ndescription: A reference for the Trippy privileges.\nsidebar:\n order: 2\nslug: 0.12.2/guides/privil"
},
{
"path": "docs/src/content/docs/0.12.2/guides/recommendation.md",
"chars": 7294,
"preview": "---\ntitle: Recommended Tracing Settings\ndescription: Recommended settings for Trippy.\nsidebar:\n order: 3\nslug: 0.12.2/g"
},
{
"path": "docs/src/content/docs/0.12.2/guides/usage.md",
"chars": 4254,
"preview": "---\ntitle: Usage Examples\ndescription: Examples of how to use the Trippy command line interface.\nsidebar:\n order: 1\nslu"
},
{
"path": "docs/src/content/docs/0.12.2/guides/windows_firewall.md",
"chars": 925,
"preview": "---\ntitle: Windows Defender Firewall\ndescription: Allow incoming ICMP traffic in the Windows Defender firewall.\nsidebar:"
},
{
"path": "docs/src/content/docs/0.12.2/index.mdx",
"chars": 2530,
"preview": "---\ntitle: \"Trippy: a network diagnostic tool\"\ndescription: a network diagnostic tool.\ntemplate: splash\nhero:\n tagline:"
},
{
"path": "docs/src/content/docs/0.12.2/reference/bindings.md",
"chars": 4222,
"preview": "---\ntitle: Key Bindings Reference\ndescription: A reference for customizing the Trippy TUI key bindings.\nsidebar:\n order"
},
{
"path": "docs/src/content/docs/0.12.2/reference/cli.md",
"chars": 9034,
"preview": "---\ntitle: CLI Reference\ndescription: A reference for the Trippy command line interface.\nsidebar:\n order: 1\nslug: 0.12."
},
{
"path": "docs/src/content/docs/0.12.2/reference/column.md",
"chars": 10342,
"preview": "---\ntitle: Column Reference\ndescription: A reference for customizing the Trippy TUI columns.\nsidebar:\n order: 4\nslug: 0"
},
{
"path": "docs/src/content/docs/0.12.2/reference/configuration.md",
"chars": 1070,
"preview": "---\ntitle: Configuration Reference\ndescription: A reference for customizing the Trippy configuration.\nsidebar:\n order: "
},
{
"path": "docs/src/content/docs/0.12.2/reference/locale.md",
"chars": 1048,
"preview": "---\ntitle: Locale Reference\ndescription: A reference for customizing the Trippy TUI locale.\nsidebar:\n order: 6\n badge:"
},
{
"path": "docs/src/content/docs/0.12.2/reference/theme.md",
"chars": 5101,
"preview": "---\ntitle: Theme Reference\ndescription: A reference for customizing the Trippy TUI theme.\nsidebar:\n order: 5\nslug: 0.12"
},
{
"path": "docs/src/content/docs/0.12.2/reference/version.md",
"chars": 2125,
"preview": "---\ntitle: Version Reference\ndescription: A reference for the Trippy versions.\nsidebar:\n order: 7\nslug: 0.12.2/referenc"
},
{
"path": "docs/src/content/docs/0.12.2/start/features.md",
"chars": 2467,
"preview": "---\ntitle: Features\ndescription: Learn about the features of Trippy.\nsidebar:\n order: 3\nslug: 0.12.2/start/features\n---"
},
{
"path": "docs/src/content/docs/0.12.2/start/getting-started.mdx",
"chars": 1741,
"preview": "---\ntitle: Getting Started\ndescription: Get started with Trippy.\nsidebar:\n order: 1\nslug: 0.12.2/start/getting-started\n"
},
{
"path": "docs/src/content/docs/0.12.2/start/installation.md",
"chars": 11694,
"preview": "---\ntitle: Installation\ndescription: Install Trippy on your platform.\nsidebar:\n order: 2\nslug: 0.12.2/start/installatio"
},
{
"path": "docs/src/content/docs/0.13.0/development/crates.md",
"chars": 1439,
"preview": "---\ntitle: Crates\ndescription: A reference for the Trippy crates.\nslug: 0.13.0/development/crates\n---\n\nThe following tab"
},
{
"path": "docs/src/content/docs/0.13.0/guides/faq.md",
"chars": 1094,
"preview": "---\ntitle: Frequently Asked Questions\ndescription: Frequently asked questions about Trippy.\nsidebar:\n order: 5\nslug: 0."
},
{
"path": "docs/src/content/docs/0.13.0/guides/privileges.md",
"chars": 1977,
"preview": "---\ntitle: Privileges\ndescription: A reference for the Trippy privileges.\nsidebar:\n order: 2\nslug: 0.13.0/guides/privil"
},
{
"path": "docs/src/content/docs/0.13.0/guides/recommendation.md",
"chars": 7294,
"preview": "---\ntitle: Recommended Tracing Settings\ndescription: Recommended settings for Trippy.\nsidebar:\n order: 3\nslug: 0.13.0/g"
},
{
"path": "docs/src/content/docs/0.13.0/guides/usage.md",
"chars": 4339,
"preview": "---\ntitle: Usage Examples\ndescription: Examples of how to use the Trippy command line interface.\nsidebar:\n order: 1\nslu"
},
{
"path": "docs/src/content/docs/0.13.0/guides/windows_firewall.md",
"chars": 925,
"preview": "---\ntitle: Windows Defender Firewall\ndescription: Allow incoming ICMP traffic in the Windows Defender firewall.\nsidebar:"
}
]
// ... and 57 more files (download for full content)
About this extraction
This page contains the full source code of the fujiapple852/trippy GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 257 files (1.6 MB), approximately 445.3k tokens, and a symbol index with 2068 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.