Repository: fujiapple852/trippy (language: rust)

Issue:
Add flag to bypass platform privilege checks
Add a `unsafe-assume-privileged` configuration option which will bypass the existing platform specific privilege checks.  

This option can be helpful for execution environments which use non-standard techniques to allow unprivileged processes to create raw sockets which cannot be detected automatically.

~~One such environment is `snap` packages, where `trip` runs with the `network-observe` interface which allows for raw sockets without elevated privileges, but does not set `CAP_NET_RAW` and as such `trip` must be run with elevated privileges.~~


Discussion / hints:

Fix patch:
diff --git a/src/config.rs b/src/config.rs
index 7bb85940b..85e2925d9 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -364,6 +364,12 @@ impl TrippyConfig {
             cfg_file_trace.unprivileged,
             defaults::DEFAULT_PRIVILEGE_MODE.is_unprivileged(),
         );
+        let unsafe_assume_privileged = cfg_layer_bool_flag(
+            args.unsafe_assume_privileged,
+            cfg_file_trace.unsafe_assume_privileged,
+            constants::DEFAULT_UNSAFE_ASSUME_PRIVILEGED,
+        );
+        let effective_has_privileges = has_privileges || unsafe_assume_privileged;
         let privilege_mode = if unprivileged {
             PrivilegeMode::Unprivileged
         } else {
@@ -646,7 +652,7 @@ impl TrippyConfig {
             Some(n) if n > 0 => Some(n),
             _ => None,
         };
-        validate_privilege(privilege_mode, has_privileges, needs_privileges)?;
+        validate_privilege(privilege_mode, effective_has_privileges, needs_privileges)?;
         validate_logging(mode, verbose)?;
         validate_strategy(multipath_strategy, unprivileged)?;
         validate_protocol_strategy(protocol, multipath_strategy)?;
@@ -1597,6 +1603,7 @@ mod tests {
     #[test_case("trip example.com --unprivileged", false, false, Ok(cfg().privilege_mode(PrivilegeMode::Unprivileged).build()); "no privilege and not needs in unprivileged mode")]
     #[test_case("trip example.com --unprivileged", false, true, Err(anyhow!("unprivileged mode not supported on this platform\n\nsee https://github.com/fujiapple852/trippy#privileges for details")); "no privilege and needs in unprivileged mode")]
     #[test_case("trip example.com --unprivileged", true, true, Err(anyhow!("unprivileged mode not supported on this platform (hint: process is privileged so disable unprivileged mode)\n\nsee https://github.com/fujiapple852/trippy#privileges for details")); "has privilege and needs in unprivileged mode")]
+    #[test_case("trip example.com --unsafe-assume-privileged", false, false, Ok(cfg().privilege_mode(PrivilegeMode::Privileged).build()); "unsafe assume privileged")]
     fn test_privilege(
         cmd: &str,
         has_privileges: bool,
diff --git a/src/config/cmd.rs b/src/config/cmd.rs
index c11decde4..4a79471f5 100644
--- a/src/config/cmd.rs
+++ b/src/config/cmd.rs
@@ -30,6 +30,10 @@ pub struct Args {
     #[arg(short = 'u', long)]
     pub unprivileged: bool,
 
+    /// Assume elevated privileges [default: false]
+    #[arg(long)]
+    pub unsafe_assume_privileged: bool,
+
     /// Tracing protocol [default: icmp]
     #[arg(value_enum, short = 'p', long)]
     pub protocol: Option<ProtocolConfig>,
diff --git a/src/config/constants.rs b/src/config/constants.rs
index bbb1f5d9a..15a38d7bd 100644
--- a/src/config/constants.rs
+++ b/src/config/constants.rs
@@ -13,7 +13,10 @@ pub const MAX_HOPS: usize = u8::MAX as usize;
 /// The default value for `mode`.
 pub const DEFAULT_MODE: Mode = Mode::Tui;
 
-/// The default value for `all_resolved_ips`.
+/// The default value for `unsafe-assume-privileged`.
+pub const DEFAULT_UNSAFE_ASSUME_PRIVILEGED: bool = false;
+
+/// The default value for `all-resolved-ips`.
 pub const DEFAULT_DNS_RESOLVE_ALL: bool = false;
 
 /// The default value for `log-format`.
@@ -55,7 +58,7 @@ pub const DEFAULT_TUI_ADDRESS_MODE: AddressMode = AddressMode::Host;
 /// The default value for `tui-refresh-rate`.
 pub const DEFAULT_TUI_REFRESH_RATE: &str = "100ms";
 
-/// The default value for `tui_privacy_max_ttl`.
+/// The default value for `tui-privacy-max-ttl`.
 pub const DEFAULT_TUI_PRIVACY_MAX_TTL: u8 = 0;
 
 /// The default value for `dns-resolve-method`.
diff --git a/src/config/file.rs b/src/config/file.rs
index a9fe30c03..7cbe751f2 100644
--- a/src/config/file.rs
+++ b/src/config/file.rs
@@ -106,6 +106,7 @@ impl Default for ConfigFile {
 pub struct ConfigTrippy {
     pub mode: Option<Mode>,
     pub unprivileged: Option<bool>,
+    pub unsafe_assume_privileged: Option<bool>,
     pub log_format: Option<LogFormat>,
     pub log_filter: Option<String>,
     pub log_span_events: Option<LogSpanEvents>,
@@ -116,6 +117,7 @@ impl Default for ConfigTrippy {
         Self {
             mode: Some(super::constants::DEFAULT_MODE),
             unprivileged: Some(defaults::DEFAULT_PRIVILEGE_MODE.is_unprivileged()),
+            unsafe_assume_privileged: Some(super::constants::DEFAULT_UNSAFE_ASSUME_PRIVILEGED),
             log_format: Some(super::constants::DEFAULT_LOG_FORMAT),
             log_filter: Some(String::from(super::constants::DEFAULT_LOG_FILTER)),
             log_span_events: Some(super::constants::DEFAULT_LOG_SPAN_EVENTS),
diff --git a/trippy-config-sample.toml b/trippy-config-sample.toml
index f970ed4e6..423cab01e 100644
--- a/trippy-config-sample.toml
+++ b/trippy-config-sample.toml
@@ -44,6 +44,16 @@ mode = "tui"
 # Note: not supported on all platforms.
 unprivileged = false
 
+# Assume elevated privileges [default: false]
+#
+# This option can be helpful for execution environments which use non-standard
+# techniques to allow unprivileged processes to create raw sockets which cannot
+# be detected automatically.
+#
+# Warning: setting this option to true will bypass platform specifc checks for
+# elevated privileges and as a result ungraceful runtime failures may occur.
+unsafe-assume-privileged = false
+
 # How to format log data.
 #
 # Allowed values are:


Test patch:
diff --git a/test_resources/config/completions_bash.txt b/test_resources/config/completions_bash.txt
index acc01122c..f409c90b2 100644
--- a/test_resources/config/completions_bash.txt
+++ b/test_resources/config/completions_bash.txt
@@ -19,7 +19,7 @@ _trip() {
 
     case "${cmd}" in
         trip)
-            opts="-c -m -u -p -F -4 -6 -P -S -A -I -i -T -g -R -U -f -t -Q -e -r -y -z -a -M -s -C -G -v -h -V --config-file --mode --unprivileged --protocol --udp --tcp --icmp --addr-family --ipv4 --ipv6 --target-port --source-port --source-address --interface --min-round-duration --max-round-duration --grace-duration --initial-sequence --multipath-strategy --max-inflight --first-ttl --max-ttl --packet-size --payload-pattern --tos --icmp-extensions --read-timeout --dns-resolve-method --dns-resolve-all --dns-timeout --dns-lookup-as-info --tui-address-mode --tui-as-mode --tui-custom-columns --tui-icmp-extension-mode --tui-geoip-mode --tui-max-addrs --tui-max-samples --tui-max-flows --tui-preserve-screen --tui-refresh-rate --tui-privacy-max-ttl --tui-theme-colors --print-tui-theme-items --tui-key-bindings --print-tui-binding-commands --report-cycles --geoip-mmdb-file --generate --print-config-template --log-format --log-filter --log-span-events --verbose --help --version [TARGETS]..."
+            opts="-c -m -u -p -F -4 -6 -P -S -A -I -i -T -g -R -U -f -t -Q -e -r -y -z -a -M -s -C -G -v -h -V --config-file --mode --unprivileged --unsafe-assume-privileged --protocol --udp --tcp --icmp --addr-family --ipv4 --ipv6 --target-port --source-port --source-address --interface --min-round-duration --max-round-duration --grace-duration --initial-sequence --multipath-strategy --max-inflight --first-ttl --max-ttl --packet-size --payload-pattern --tos --icmp-extensions --read-timeout --dns-resolve-method --dns-resolve-all --dns-timeout --dns-lookup-as-info --tui-address-mode --tui-as-mode --tui-custom-columns --tui-icmp-extension-mode --tui-geoip-mode --tui-max-addrs --tui-max-samples --tui-max-flows --tui-preserve-screen --tui-refresh-rate --tui-privacy-max-ttl --tui-theme-colors --print-tui-theme-items --tui-key-bindings --print-tui-binding-commands --report-cycles --geoip-mmdb-file --generate --print-config-template --log-format --log-filter --log-span-events --verbose --help --version [TARGETS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
diff --git a/test_resources/config/completions_elvish.txt b/test_resources/config/completions_elvish.txt
index 7fa744360..0b725dec6 100644
--- a/test_resources/config/completions_elvish.txt
+++ b/test_resources/config/completions_elvish.txt
@@ -82,6 +82,7 @@ set edit:completion:arg-completer[trip] = {|@words|
             cand --log-span-events 'The debug log format [default: off]'
             cand -u 'Trace without requiring elevated privileges on supported platforms [default: false]'
             cand --unprivileged 'Trace without requiring elevated privileges on supported platforms [default: false]'
+            cand --unsafe-assume-privileged 'Assume elevated privileges [default: false]'
             cand --udp 'Trace using the UDP protocol'
             cand --tcp 'Trace using the TCP protocol'
             cand --icmp 'Trace using the ICMP protocol'
diff --git a/test_resources/config/completions_fish.txt b/test_resources/config/completions_fish.txt
index b291578c3..84f5bc56b 100644
--- a/test_resources/config/completions_fish.txt
+++ b/test_resources/config/completions_fish.txt
@@ -39,6 +39,7 @@ complete -c trip -l log-format -d 'The debug log format [default: pretty]' -r -f
 complete -c trip -l log-filter -d 'The debug log filter [default: trippy=debug]' -r
 complete -c trip -l log-span-events -d 'The debug log format [default: off]' -r -f -a "{off	'Do not display event spans',active	'Display enter and exit event spans',full	'Display all event spans'}"
 complete -c trip -s u -l unprivileged -d 'Trace without requiring elevated privileges on supported platforms [default: false]'
+complete -c trip -l unsafe-assume-privileged -d 'Assume elevated privileges [default: false]'
 complete -c trip -l udp -d 'Trace using the UDP protocol'
 complete -c trip -l tcp -d 'Trace using the TCP protocol'
 complete -c trip -l icmp -d 'Trace using the ICMP protocol'
diff --git a/test_resources/config/completions_powershell.txt b/test_resources/config/completions_powershell.txt
index 9916b068a..4a25c465d 100644
--- a/test_resources/config/completions_powershell.txt
+++ b/test_resources/config/completions_powershell.txt
@@ -85,6 +85,7 @@ Register-ArgumentCompleter -Native -CommandName 'trip' -ScriptBlock {
             [CompletionResult]::new('--log-span-events', 'log-span-events', [CompletionResultType]::ParameterName, 'The debug log format [default: off]')
             [CompletionResult]::new('-u', 'u', [CompletionResultType]::ParameterName, 'Trace without requiring elevated privileges on supported platforms [default: false]')
             [CompletionResult]::new('--unprivileged', 'unprivileged', [CompletionResultType]::ParameterName, 'Trace without requiring elevated privileges on supported platforms [default: false]')
+            [CompletionResult]::new('--unsafe-assume-privileged', 'unsafe-assume-privileged', [CompletionResultType]::ParameterName, 'Assume elevated privileges [default: false]')
             [CompletionResult]::new('--udp', 'udp', [CompletionResultType]::ParameterName, 'Trace using the UDP protocol')
             [CompletionResult]::new('--tcp', 'tcp', [CompletionResultType]::ParameterName, 'Trace using the TCP protocol')
             [CompletionResult]::new('--icmp', 'icmp', [CompletionResultType]::ParameterName, 'Trace using the ICMP protocol')
diff --git a/test_resources/config/completions_zsh.txt b/test_resources/config/completions_zsh.txt
index b0bb2648a..3041b6432 100644
--- a/test_resources/config/completions_zsh.txt
+++ b/test_resources/config/completions_zsh.txt
@@ -135,6 +135,7 @@ active\:"Display enter and exit event spans"
 full\:"Display all event spans"))' \
 '-u[Trace without requiring elevated privileges on supported platforms \[default\: false\]]' \
 '--unprivileged[Trace without requiring elevated privileges on supported platforms \[default\: false\]]' \
+'--unsafe-assume-privileged[Assume elevated privileges \[default\: false\]]' \
 '(-p --protocol --tcp --icmp)--udp[Trace using the UDP protocol]' \
 '(-p --protocol --udp --icmp)--tcp[Trace using the TCP protocol]' \
 '(-p --protocol --udp --tcp)--icmp[Trace using the ICMP protocol]' \
diff --git a/test_resources/config/usage_long.txt b/test_resources/config/usage_long.txt
index ebfa241af..0db759306 100644
--- a/test_resources/config/usage_long.txt
+++ b/test_resources/config/usage_long.txt
@@ -27,6 +27,9 @@ Options:
   -u, --unprivileged
           Trace without requiring elevated privileges on supported platforms [default: false]
 
+      --unsafe-assume-privileged
+          Assume elevated privileges [default: false]
+
   -p, --protocol <PROTOCOL>
           Tracing protocol [default: icmp]
 
diff --git a/test_resources/config/usage_short.txt b/test_resources/config/usage_short.txt
index 5c4d6788a..88325ae6f 100644
--- a/test_resources/config/usage_short.txt
+++ b/test_resources/config/usage_short.txt
@@ -6,65 +6,119 @@ Arguments:
   [TARGETS]...  A space delimited list of hostnames and IPs to trace
 
 Options:
-  -c, --config-file <CONFIG_FILE>                          Config file
-  -m, --mode <MODE>                                        Output mode [default: tui] [possible values: tui, stream, pretty, markdown, csv, json, dot,
-                                                           flows, silent]
-  -u, --unprivileged                                       Trace without requiring elevated privileges on supported platforms [default: false]
-  -p, --protocol <PROTOCOL>                                Tracing protocol [default: icmp] [possible values: icmp, udp, tcp]
-      --udp                                                Trace using the UDP protocol
-      --tcp                                                Trace using the TCP protocol
-      --icmp                                               Trace using the ICMP protocol
-  -F, --addr-family <ADDR_FAMILY>                          The address family [default: Ipv4thenIpv6] [possible values: ipv4, ipv6, ipv6-then-ipv4,
-                                                           ipv4-then-ipv6]
-  -4, --ipv4                                               Use IPv4 only
-  -6, --ipv6                                               Use IPv6 only
-  -P, --target-port <TARGET_PORT>                          The target port (TCP & UDP only) [default: 80]
-  -S, --source-port <SOURCE_PORT>                          The source port (TCP & UDP only) [default: auto]
-  -A, --source-address <SOURCE_ADDRESS>                    The source IP address [default: auto]
-  -I, --interface <INTERFACE>                              The network interface [default: auto]
-  -i, --min-round-duration <MIN_ROUND_DURATION>            The minimum duration of every round [default: 1s]
-  -T, --max-round-duration <MAX_ROUND_DURATION>            The maximum duration of every round [default: 1s]
-  -g, --grace-duration <GRACE_DURATION>                    The period of time to wait for additional ICMP responses after the target has responded [default:
-                                                           100ms]
-      --initial-sequence <INITIAL_SEQUENCE>                The initial sequence number [default: 33000]
-  -R, --multipath-strategy <MULTIPATH_STRATEGY>            The Equal-cost Multi-Path routing strategy (UDP only) [default: classic] [possible values:
-                                                           classic, paris, dublin]
-  -U, --max-inflight <MAX_INFLIGHT>                        The maximum number of in-flight ICMP echo requests [default: 24]
-  -f, --first-ttl <FIRST_TTL>                              The TTL to start from [default: 1]
-  -t, --max-ttl <MAX_TTL>                                  The maximum number of TTL hops [default: 64]
-      --packet-size <PACKET_SIZE>                          The size of IP packet to send (IP header + ICMP header + payload) [default: 84]
-      --payload-pattern <PAYLOAD_PATTERN>                  The repeating pattern in the payload of the ICMP packet [default: 0]
-  -Q, --tos <TOS>                                          The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]
-  -e, --icmp-extensions                                    Parse ICMP extensions
-      --read-timeout <READ_TIMEOUT>                        The socket read timeout [default: 10ms]
-  -r, --dns-resolve-method <DNS_RESOLVE_METHOD>            How to perform DNS queries [default: system] [possible values: system, resolv, google,
-                                                           cloudflare]
-  -y, --dns-resolve-all                                    Trace to all IPs resolved from DNS lookup [default: false]
-      --dns-timeout <DNS_TIMEOUT>                          The maximum time to wait to perform DNS queries [default: 5s]
-  -z, --dns-lookup-as-info                                 Lookup autonomous system (AS) information during DNS queries [default: false]
-  -a, --tui-address-mode <TUI_ADDRESS_MODE>                How to render addresses [default: host] [possible values: ip, host, both]
-      --tui-as-mode <TUI_AS_MODE>                          How to render AS information [default: asn] [possible values: asn, prefix, country-code,
-                                                           registry, allocated, name]
-      --tui-custom-columns <TUI_CUSTOM_COLUMNS>            Custom columns to be displayed in the TUI hops table [default: holsravbwdt]
-      --tui-icmp-extension-mode <TUI_ICMP_EXTENSION_MODE>  How to render ICMP extensions [default: off] [possible values: off, mpls, full, all]
-      --tui-geoip-mode <TUI_GEOIP_MODE>                    How to render GeoIp information [default: short] [possible values: off, short, long, location]
-  -M, --tui-max-addrs <TUI_MAX_ADDRS>                      The maximum number of addresses to show per hop [default: auto]
-  -s, --tui-max-samples <TUI_MAX_SAMPLES>                  The maximum number of samples to record per hop [default: 256]
-      --tui-max-flows <TUI_MAX_FLOWS>                      The maximum number of flows to show [default: 64]
-      --tui-preserve-screen                                Preserve the screen on exit [default: false]
-      --tui-refresh-rate <TUI_REFRESH_RATE>                The Tui refresh rate [default: 100ms]
-      --tui-privacy-max-ttl <TUI_PRIVACY_MAX_TTL>          The maximum ttl of hops which will be masked for privacy [default: 0]
-      --tui-theme-colors <TUI_THEME_COLORS>                The TUI theme colors [item=color,item=color,..]
-      --print-tui-theme-items                              Print all TUI theme items and exit
-      --tui-key-bindings <TUI_KEY_BINDINGS>                The TUI key bindings [command=key,command=key,..]
-      --print-tui-binding-commands                         Print all TUI commands that can be bound and exit
-  -C, --report-cycles <REPORT_CYCLES>                      The number of report cycles to run [default: 10]
-  -G, --geoip-mmdb-file <GEOIP_MMDB_FILE>                  The supported MaxMind or IPinfo GeoIp mmdb file
-      --generate <GENERATE>                                Generate shell completion [possible values: bash, elvish, fish, powershell, zsh]
-      --print-config-template                              Print a template toml config file and exit
-      --log-format <LOG_FORMAT>                            The debug log format [default: pretty] [possible values: compact, pretty, json, chrome]
-      --log-filter <LOG_FILTER>                            The debug log filter [default: trippy=debug]
-      --log-span-events <LOG_SPAN_EVENTS>                  The debug log format [default: off] [possible values: off, active, full]
-  -v, --verbose                                            Enable verbose debug logging
-  -h, --help                                               Print help (see more with '--help')
-  -V, --version                                            Print version
+  -c, --config-file <CONFIG_FILE>
+          Config file
+  -m, --mode <MODE>
+          Output mode [default: tui] [possible values: tui, stream, pretty, markdown, csv, json, dot, flows, silent]
+  -u, --unprivileged
+          Trace without requiring elevated privileges on supported platforms [default: false]
+      --unsafe-assume-privileged
+          Assume elevated privileges [default: false]
+  -p, --protocol <PROTOCOL>
+          Tracing protocol [default: icmp] [possible values: icmp, udp, tcp]
+      --udp
+          Trace using the UDP protocol
+      --tcp
+          Trace using the TCP protocol
+      --icmp
+          Trace using the ICMP protocol
+  -F, --addr-family <ADDR_FAMILY>
+          The address family [default: Ipv4thenIpv6] [possible values: ipv4, ipv6, ipv6-then-ipv4, ipv4-then-ipv6]
+  -4, --ipv4
+          Use IPv4 only
+  -6, --ipv6
+          Use IPv6 only
+  -P, --target-port <TARGET_PORT>
+          The target port (TCP & UDP only) [default: 80]
+  -S, --source-port <SOURCE_PORT>
+          The source port (TCP & UDP only) [default: auto]
+  -A, --source-address <SOURCE_ADDRESS>
+          The source IP address [default: auto]
+  -I, --interface <INTERFACE>
+          The network interface [default: auto]
+  -i, --min-round-duration <MIN_ROUND_DURATION>
+          The minimum duration of every round [default: 1s]
+  -T, --max-round-duration <MAX_ROUND_DURATION>
+          The maximum duration of every round [default: 1s]
+  -g, --grace-duration <GRACE_DURATION>
+          The period of time to wait for additional ICMP responses after the target has responded [default: 100ms]
+      --initial-sequence <INITIAL_SEQUENCE>
+          The initial sequence number [default: 33000]
+  -R, --multipath-strategy <MULTIPATH_STRATEGY>
+          The Equal-cost Multi-Path routing strategy (UDP only) [default: classic] [possible values: classic, paris,
+          dublin]
+  -U, --max-inflight <MAX_INFLIGHT>
+          The maximum number of in-flight ICMP echo requests [default: 24]
+  -f, --first-ttl <FIRST_TTL>
+          The TTL to start from [default: 1]
+  -t, --max-ttl <MAX_TTL>
+          The maximum number of TTL hops [default: 64]
+      --packet-size <PACKET_SIZE>
+          The size of IP packet to send (IP header + ICMP header + payload) [default: 84]
+      --payload-pattern <PAYLOAD_PATTERN>
+          The repeating pattern in the payload of the ICMP packet [default: 0]
+  -Q, --tos <TOS>
+          The TOS (i.e. DSCP+ECN) IP header value (TCP and UDP only) [default: 0]
+  -e, --icmp-extensions
+          Parse ICMP extensions
+      --read-timeout <READ_TIMEOUT>
+          The socket read timeout [default: 10ms]
+  -r, --dns-resolve-method <DNS_RESOLVE_METHOD>
+          How to perform DNS queries [default: system] [possible values: system, resolv, google, cloudflare]
+  -y, --dns-resolve-all
+          Trace to all IPs resolved from DNS lookup [default: false]
+      --dns-timeout <DNS_TIMEOUT>
+          The maximum time to wait to perform DNS queries [default: 5s]
+  -z, --dns-lookup-as-info
+          Lookup autonomous system (AS) information during DNS queries [default: false]
+  -a, --tui-address-mode <TUI_ADDRESS_MODE>
+          How to render addresses [default: host] [possible values: ip, host, both]
+      --tui-as-mode <TUI_AS_MODE>
+          How to render AS information [default: asn] [possible values: asn, prefix, country-code, registry, allocated,
+          name]
+      --tui-custom-columns <TUI_CUSTOM_COLUMNS>
+          Custom columns to be displayed in the TUI hops table [default: holsravbwdt]
+      --tui-icmp-extension-mode <TUI_ICMP_EXTENSION_MODE>
+          How to render ICMP extensions [default: off] [possible values: off, mpls, full, all]
+      --tui-geoip-mode <TUI_GEOIP_MODE>
+          How to render GeoIp information [default: short] [possible values: off, short, long, location]
+  -M, --tui-max-addrs <TUI_MAX_ADDRS>
+          The maximum number of addresses to show per hop [default: auto]
+  -s, --tui-max-samples <TUI_MAX_SAMPLES>
+          The maximum number of samples to record per hop [default: 256]
+      --tui-max-flows <TUI_MAX_FLOWS>
+          The maximum number of flows to show [default: 64]
+      --tui-preserve-screen
+          Preserve the screen on exit [default: false]
+      --tui-refresh-rate <TUI_REFRESH_RATE>
+          The Tui refresh rate [default: 100ms]
+      --tui-privacy-max-ttl <TUI_PRIVACY_MAX_TTL>
+          The maximum ttl of hops which will be masked for privacy [default: 0]
+      --tui-theme-colors <TUI_THEME_COLORS>
+          The TUI theme colors [item=color,item=color,..]
+      --print-tui-theme-items
+          Print all TUI theme items and exit
+      --tui-key-bindings <TUI_KEY_BINDINGS>
+          The TUI key bindings [command=key,command=key,..]
+      --print-tui-binding-commands
+          Print all TUI commands that can be bound and exit
+  -C, --report-cycles <REPORT_CYCLES>
+          The number of report cycles to run [default: 10]
+  -G, --geoip-mmdb-file <GEOIP_MMDB_FILE>
+          The supported MaxMind or IPinfo GeoIp mmdb file
+      --generate <GENERATE>
+          Generate shell completion [possible values: bash, elvish, fish, powershell, zsh]
+      --print-config-template
+          Print a template toml config file and exit
+      --log-format <LOG_FORMAT>
+          The debug log format [default: pretty] [possible values: compact, pretty, json, chrome]
+      --log-filter <LOG_FILTER>
+          The debug log filter [default: trippy=debug]
+      --log-span-events <LOG_SPAN_EVENTS>
+          The debug log format [default: off] [possible values: off, active, full]
+  -v, --verbose
+          Enable verbose debug logging
+  -h, --help
+          Print help (see more with '--help')
+  -V, --version
+          Print version