LFT(8)

NAME
lft - display the route packets take to a network host/socket using one of several layer-4 protocols and methods; optionally show heuristic network information in transitu

SYNOPSIS
lft [-d dport] [-s sport] [-m retry min] [-M retry max] [-a ahead] [-c scatter ms] [-t timeout ms] [-l min ttl] [-H max ttl] [-L length] [-q ISN] [-D device] [-f device] [-G icons path] [-ACEINPRSTUVbeghinpruvxyzK] [<gateway> <...>] target:dport

DESCRIPTION
The Internet is a large and complex aggregation of network hardware, connected together by gateways. Tracking the route one's packets follow (or finding the miscreant gateway that's discarding your packets) can be difficult. (from traceroute(8))

lft was developed to automate a solution to the above, taking into account that modern networks contain many configurations of load balancers, proxies, and stateful firewalls.

lft implements numerous network tracing methods and strategies. Generally, lft sends various types of layer-4 probes utilizing the IP protocol `time to live' field and attempts to elicit an ICMP `time exceeded in transit' response from each gateway along the path to some host. RFC 1393 Traceroute Using an IP Option is also available as one of several tracing methods.

lft additionally listens for various messages along the way to assist network managers in ascertaining per-protocol heuristic routing information. lft can optionally retrieve various information about the networks it traverses using a variety of sources such as registries, routing arbiters, etc.

The only mandatory parameter is the target host name or IP number. Options toggle the display of more interesting data or change the variables of the trace itself. The (-E/-e) adaptive option tries several combinations of TCP states (changing flags inside the probes it sends) in order to improve the chances of a successful trace and expose stateful packet filters.

Other options are:

-d dport, --dport dport
    Set dport as the destination TCP port of the probes LFT generates. Default is 443. This option is useful to see if packets follow a different route based on protocol destination, a likely scenario when load balancers or proxies are involved. This option may also bypass less sophisticated packet filter configurations.

-s sport, --sport sport
    Set sport as the origin TCP port of the probes LFT generates. By default, LFT selects a random port from the IANA dynamic port range (49152–65535). This option is useful to see if packets follow a different route based on protocol source. This option may also bypass less sophisticated packet filter configurations.

-z, --random-sport
    Re-randomize the source port, selecting a new random port from the IANA dynamic range (49152–65535) for this invocation. Useful when you want to ensure a fresh port selection rather than reusing one from a prior run or a local packet filter or proxy that may restrict specific source port values.

-m min, --min-probes min
    Set min as the minimum number of probes to send per hop. Default is 1.

-M max, --max-probes max
    Set max as the maximum number of probes to send per hop. Default is 2.

-a ahead, --ahead ahead
    Set ahead as the number of hops forward to query before waiting for a response. Default is 5.

-c scatter ms, --scatter scatter ms
    Set scatter ms as the minimum number of milliseconds to wait between sending probes. Default is 20.

-t timeout ms, --timeout timeout ms
    Set timeout ms as the maximum number of milliseconds to wait before assuming a probe was lost/discarded. Default is 250.

-l min ttl, --min-ttl min ttl, --first-hop min ttl
    Set min ttl as the minimum TTL (time-to-live) on outgoing probes (essentially, the first hop in the line that you want to display). Default is 1.

-q ISN, --isn ISN
    Set ISN as the ISN (initial sequence number) of the first probe. If unset, one will be automatically generated using a pseudo-random, time-seeded algorithm.

-w window, --tcp-window window
    Set window as the TCP window size advertised in outgoing probe packets, in bytes. This option applies to TCP-based traces only. Default is 32768.

-L length, --length length, --bytes length
    Set length as the size of probe packets in bytes. This includes layer-3 and layer-4 headers, but does not include layer-2 headers. For example, setting the length to 1500 would create a 1500-byte probe packet which would result in a 1514-byte frame on an Ethernet network. This option is silently ignored when -K is active; probe size is managed automatically by PMTUD.

-K, --mtu, --path-mtu
    Enable active Path MTU Discovery (PMTUD). When this flag is set, lft queries the local interface MTU via ioctl(2) SIOCGIFMTU and starts probing at that size (typically 1500 bytes for Ethernet, up to 9000 for jumbo frames). All probes carry the DF (Don't Fragment) bit, which is already lft's default.

    When a router cannot forward a probe because it exceeds an outbound link MTU, it returns an ICMP “fragmentation needed” message (type 3, code 4) containing the next-hop MTU. This class of message is colloquially called a “PTB” (Packet Too Big), a term that strictly refers to ICMPv6 Type 2 but is widely used for both IPv4 and IPv6. lft records the MTU at the responding hop and reduces subsequent probe sizes accordingly.

    If a router silently drops an oversized DF probe without returning an ICMP message (a PMTUD black hole), lft flags the hop as “[MTU Limit]” and steps down to the next RFC 1191 plateau value to continue probing beyond the black hole.

    PMTUD measures the forward-path MTU only; the return path may differ. Discovery stops at the first hop that limits the path MTU; hops beyond it see reduced-size probes that pass freely.

    Probe design and known limitations. lft implements PMTUD by inflating the payload of its existing TCP, UDP, and ICMP probes to the current MTU estimate. For TCP probes, strictly speaking, SYN, FIN, and RST segments should carry no payload; some deep-packet-inspection firewalls enforce this and will drop oversized probes before they reach a bottleneck link. UDP datagrams and ICMP echo requests may carry any payload size without protocol violation. This is a known constraint of the technique for TCP mode.

    An alternative approach — sending ICMP echo requests exclusively for MTU probing, as ping(8) does with -M do — was considered but rejected. ICMP traffic is routinely deprioritized in router control planes and discarded wholesale by enterprise firewalls, making it a less faithful representation of real traffic and no more likely to traverse a restricted path than a TCP probe.

    The payload-inflation approach is preferred because it exercises the same forwarding path as real application traffic. PTB messages are generated by routers at the IP layer, before any TCP inspection occurs, so the bottleneck is still correctly identified even when the probe carries an atypical payload. On the public Internet backbone — where MTU constraints most commonly arise — core routers perform IP-layer forwarding without TCP payload inspection, and the technique works reliably. Paths that traverse DPI firewalls configured to reject TCP-with-payload would equally reject any active PMTUD probing strategy; this is not a limitation specific to lft.

-D device, --device device, --receive-device device
    Set device as the network device or address to receive traffic. (e.g., "en1" or "1.2.3.4") If unset, lft will attempt to determine and acquire the appropriate interface based on routing.

-f device, --from-device device, --source-device device
    Set device as the network device or address to transmit traffic. (e.g., "en1" or "1.2.3.4") If unset, lft will attempt to determine and acquire the appropriate interface based on routing. This serves to operate lft in a passive mode where you may transmit from a (potentially) spoofed IP address on one interface, yet receive on another. This allows you to trace from a different IP address whose traffic you can see in order to intercept replies.

-H ttl, --max-hops ttl, --ttl-max ttl
    Set ttl as the maximum TTL, essentially the maximum route traversal distance in hops. Default is 30.

-G icons path, --graphviz-icons icons path
    Set icons path as the path to GraphViz icons in connection with GraphViz output.

-I, --minimize-delay
    Set the ToS (Type of Service) bit on outgoing IP datagrams. The ToS will be set to the differentiated services request minimize-delay.

-i, --ignore-unreachables
    Ignore ICMP unreachable messages; the trace continues through firewalls and other devices that send administratively-prohibited or host/net unreachable responses. By default, LFT stops the trace upon receiving any of the following ICMP unreachable codes: net unreachable (0), host unreachable (1), protocol unreachable (2), port unreachable (3), net administratively prohibited (9), host administratively prohibited (10), or communication administratively prohibited (13). This flag is implied by adaptive mode (-E).

-n, --numeric
    Print addresses numerically rather than symbolically and numerically. Disables use of the DNS resolver completely.

-h, --hostnames-only
    Print addresses symbolically rather than symbolically and numerically. If the DNS resolver fails to resolve an address, the address is printed numerically.

-E | -e, --adaptive
    Enable use of the adaptive engine which tries several combinations of TCP states (changing flags inside the probes it sends) in order to improve the chances of a successful trace. The engine also displays other useful information such as stateful inspection firewalls or broken IP stacks encountered along the way. Adaptive mode automatically implies -i (--ignore-unreachables), allowing the trace to continue through devices that send ICMP unreachable responses rather than halting.

-F, --fin
    Enable use of TCP packets with the FIN flag set. This strategy fools unsophisticated packet filters that don't maintain a proper state table. Such devices will forward the packet to its destination rather than filter it, assuming a handshake has already taken place and the probes are part of an existing and valid TCP stream.

-u, --udp
    Enable use of UDP-based probes instead of TCP-based probes. Unlike the traditional traceroute method, which increments the UDP destination port with each TTL to identify replies, LFT sends all UDP probes to the same destination port and embeds a pseudorandom session-unique identifier in the IP ID field of each probe. Replies are matched to probes via the ID value echoed back in ICMP time-exceeded messages, keeping the five-tuple (source IP, destination IP, protocol, source port, destination port) constant across all TTLs. This ensures every probe follows the same path through ECMP load-balanced networks. Many of LFT's other options (such as source and destination port selection) are still available. By default, LFT's UDP probes carry a small payload (unlike TCP probes, which carry none).

-N, --netname
    Enable lookup and display of network or AS names (e.g., [GNTY-NETBLK-4]). This option queries Prefix WhoIs, RIPE NCC, or the RADB (as requested). In the case of Prefix WhoIs or RADB, the network name is displayed. In the case of RIPE NCC, the AS name is displayed.

-P  Enable RFC 1393 tracing method using ICMP and an IP option. RFC 1393 (Traceroute Using an IP Option), published in January 1993, defined an elegant alternative to the traditional Van Jacobson traceroute method: rather than relying on TTL expiry and ICMP Time Exceeded messages, a single outbound packet carries a Traceroute IP option (type 82) that instructs each router in the path to send an ICMP Traceroute message back to the originator. In theory, this requires only n+1 packets instead of the 2n packets used by traditional traceroute.

    In practice, no major router vendor — Cisco, Juniper, Nokia, Huawei, or any other — ever implemented RFC 1393 in their forwarding path. The mechanism suffered a chicken-and-egg problem: it required every router in the path to support the new IP option, whereas Van Jacobson's 1987 traceroute exploited TTL-expiry behavior already present in all routers and was universally deployed by the time RFC 1393 arrived. IP options processing also carries security risks, as options are handled in the router's slow path (control plane) and can be exploited for DoS amplification. Over time, ISPs and enterprises increasingly configured equipment to strip or drop packets carrying IP options entirely.

    RFC 1393 never advanced beyond Experimental status. It was formally deprecated by RFC 6814 in November 2012, which moved it to Historic. RFC 7126 (February 2014) further recommends that routers SHOULD drop packets containing the Traceroute IP option, noting zero operational impact from doing so. This option is retained in lft for completeness, but is unlikely to elicit responses from any production network equipment.

-p, --icmp
    Enable use of ICMP-based probes instead of TCP-based probes. This strategy is sometimes the fastest, however firewalls commonly filter ICMP at network borders. ICMP probes are echo request (ping) packets.

-b, --basic-tcp
    Enable TCP basic tracing method. Unlike the default method, the basic method generates TCP probes without relying upon sequence numbers being conveyed correctly. This makes LFT more comptabile with networks employing NAT, but is slower than the default method. TCP basic may also be used with adaptive mode (-E).

-A, --asn
    Enable lookup and display of AS (autonomous system) numbers (e.g., [1]). This option queries one of several whois servers (see options 'C' and 'r') in order to ascertain the origin ASN of the IP address in question. By default, LFT uses the pWhoIs service whose ASN data tends to be more accurate and more timely than using the RADB as it is derived from the Internet's global routing table. See www.pwhois.org

-r, --ripe-riswhois
    Force use of the RIPE NCC RIS whois service to lookup ASNs. This is an alternative source of timely ASN-related information built using the Internet's global routing table. See www.ripe.net/projects/ris

-C, --cymru
    Force use of the Cymru whois service to lookup ASNs. This is an alternative source of timely ASN-related information built using the Internet's global routing table. See www.cymru.com

-R, --radb
    Force use of the RADB whois service to lookup ASNs. This tends to be quick, but incomplete and usually inaccurate with regard to the 'actual' Internet routing table. See www.radb.net

-T, --time-keeping
    Enable display of LFT's execution timer. This option places timers on the trace itself and on lookups and name resolution to show where LFT is spending its time, waiting on resolvers, or processing trace packets. Use with -V (verbose) to display additional detail.

-U, --time-keeping-utc
    Display all times in UTC/GMT0. This option also enables the -T option automatically.

-S, --quiet, --silent
    Suppress display of the real-time status bar. This option makes LFT show its completed trace output only, no-frills.

-x, --xml
    Enable XML output and suppress all other output to stdout.

-g, --graphviz
    Enable GraphViz output and suppress all other output to stdout.

-o, --ascii
    Display the completed trace as a horizontal ASCII art hop diagram. Each hop occupies a column showing (top to bottom): the hop header, hostname, IP address, AS number (when -A is used), network name (when -N is used), round-trip time, and a feature annotation line for seam, firewall, or target-state information.

    In -n mode the IP address appears on both the hostname and address lines for layout consistency. In -h mode the IP address line is suppressed; TTL information for cloaked hops moves to the AS number line so it shares a row with AS data from other hops rather than occupying a mostly-blank line of its own.

    Cloaked hops, seam boundaries, firewall anomalies, and target state are each marked with a distinct feature label. In Unicode mode the labels are: ‘⇶ Stateful FW’ (stateful packet-inspecting firewall), ‘⚑ Flag FW’ (flag-based packet filter), ‘⇄ BSD Bug’ (errant TTL reuse anomaly), ‘╳ ASN Seam’ (autonomous system boundary crossing), ‘╳ NET Seam’ (network boundary crossing), ‘░cloaked░’ (no-reply hop), ‘[OPEN]’, ‘[FILTERED]’, and ‘[CLOSED]’ (target port state). Plain ASCII equivalents are used on terminals that do not support Unicode.

    LFT automatically enables Unicode box-drawing characters and ANSI color when the terminal supports them (detected via TERM, COLORTERM, and isatty(3)). Set NO_COLOR to suppress color output. When the path is too wide for the terminal, the diagram wraps onto additional rows.

-j N, --stats N
    Collect N round-trip time samples per hop and display a candlestick RTT chart above the hop diagram (implies -o). Each hop column renders a box-and-whisker bar: the solid block marks the average RTT; the top cap (┬) and bottom cap (┴) mark the maximum and minimum RTTs; the thin shaft (│) between them shows the spread. Hops with no reply are rendered as a full-width column of shade blocks (░). A Y-axis with labeled RTT ticks appears at the left edge; the X-axis footer shows the end-to-end RTT range derived from the target hop's own min/max samples and the destination in proto​://​address​:​port format (e.g. ‘End-to-End RTT 15–81ms, 6 hops to tcp://208.74.248.40:443’). If the target was not reached the footer reads ‘N hops traced, target unreachable’. Columns with a jitter spread exceeding 25 ms are highlighted in yellow with a ‘⚡ Nms Δ’ annotation.

--no-ascii-chart, --no-async-chart
    Suppress the candlestick RTT chart produced by -j while still collecting and displaying per-hop RTT statistics. Useful when the terminal is too narrow for the chart, when output is piped to another tool, or when only the numerical summary (min/avg/max/jitter) is needed. Has no effect unless -j N is also specified.

-W N, --watch[=N, --continuous[=N]]
    Enable continuous monitoring mode, repeating the trace every N seconds (default: 5). LFT runs in an interactive full-screen ncurses(3) display that shows per-hop RTT history, loss percentages, and network annotation (ASN, network name, organisation) in real time.

    Subsequent cycles auto-tune the probe range and timeouts from the previously learned path; see Topology inheritance below.

    View 1 (default) shows the -o candlestick chart on the upper half of the screen with a rolling statistics table below it. View 2 replaces the chart with proportional RTT bar columns. View 3 is a full-height statistics table that shows more hops simultaneously. Switch views with 1, 2, or 3.

    The statistics table columns are:
    HOP TTL value.
    HOST
        IP address of the responding router (or PTR hostname when -h is active; see below).
    LOSS%
        Packet loss percentage across all cycles observed.
    MIN / AVG / MAX
        Minimum, mean, and maximum round-trip time in milliseconds.
    JIT Jitter (max - min over all cycles).
    ASN Autonomous system number from pWhoIs (e.g. 7922). Private and special-purpose addresses (RFC 1918, RFC 6598, loopback, link-local, etc.) are labelled with their IANA RFC tag (e.g. ‘RFC1918’) instead of a pWhoIs lookup.
    NETNAME
        Network name from pWhoIs (e.g. COMCAST-7922).
    ORGNAME
        Organisation name from pWhoIs (e.g. Comcast Cable).
    Sparkline
        Per-hop RTT history plotted as Unicode block characters, oldest sample on the left and newest on the right. Green indicates RTT within 20% of the hop average; yellow between 20% and 50% above average; magenta more than 50% above average; red indicates a lost probe.

    Intermediate hops that do not respond are shown as ‘*’ in the HOST column.

    If -j is not specified, each cycle collects 3 RTT samples per hop.

    During each trace a live counter line is displayed showing (in order): replies received (↓N), probes sent (↑N), unique responding hops (⬡ N), and target reached status (✔ or ✗). Before ncurses initialises this line appears on the terminal directly; once ncurses is running it occupies the bottom status row of every view.

    Keyboard controls:
    1 – 3
        Switch between the three display views.
    p   Pause or resume trace cycling. While paused, the status bar shows “Paused...” and no new traces run until p is pressed again.
    r   Reset all accumulated statistics (RTT history, loss counters, cycle count) and restart from a clean baseline.
    c   Clear all statistics, flush the DNS and pWhoIs cache, and redraw. This forces fresh lookups on the next cycle.
    w   Toggle pWhoIs annotation columns (ASN / NETNAME / ORGNAME). Annotation is enabled by default; a bulk pWhoIs query runs at startup and is refreshed as new hop addresses are discovered across cycles. Pressing this key shows or hides the annotation columns without discarding the cached data.
    h   Toggle hostname display: when on, the HOST column shows the PTR reverse-DNS name for each hop rather than its IP address.
    v   Open or close the log drawer, a panel at the bottom of the screen that shows the raw LFT verbose output captured during each trace cycle.
    x   Save the current screen to a file. LFT prompts for a filename (pre-filled with a timestamp) and writes both a plain-text .txt version and an ANSI-color .ansi version to the current directory.
    + / -
        Increase or decrease the interval between cycles by one second.
    q   Quit watch mode and exit.

    Path changes are detected automatically: when the set of responding hop addresses changes between cycles the change is highlighted in the status bar and held for three seconds.

    For multi-cycle traces, watch mode preserves the per-protocol ECMP flow-identifier across cycles so every cycle traverses the same ECMP branch on multi-path networks: TCP source port, UDP IP-ID base, and the ICMP sequence-number anchor are all held constant for the life of the watch session. See lft(8) notes on ECMP flow-hash stability for the underlying mechanism.

    Topology inheritance

    After the first cycle, watch mode learns the path length and RTT envelope and uses them to accelerate subsequent cycles. Once the same number of hops has been observed for three consecutive cycles, the TTL probe range narrows to learned_num_hops + --learn-margin, the in-flight probe pipeline widens to the full known path width (capped at 16), and the cloaked-hop timeout drops to max(8 × max_observed_rtt, 200 ms). A cycle that misses the target or a change in probe protocol resets the learned state, reverting to broad-scan defaults until the path stabilizes again.

    --no-learn
        Disable watch-mode topology inheritance. Every cycle probes the full default TTL ladder with the conventional ahead-limit and timeout.

    --learn-margin N
        TTL probe margin above the learned path length (default 2; clamped 0 .. 10). A larger margin notices path lengthening sooner at the cost of probing empty TTLs.

    This option requires ncurses support compiled into LFT. If ncurses was not detected at build time, --watch prints an explanatory error and exits. The minimum supported terminal height is 24 rows. Superuser privileges (via sudo(8) or a setuid-root installation) are required.

-y, --verify-seam
    Enable network seam testing in connection with GraphViz output.

-V, --verbose
    Display verbose output. Use more V's for more info.

-v, --version
    Display version information, then exit(1).

-Q, --no-async-dns
    Disable asynchronous DNS resolution. When LFT is built with c-ares support (the default when the library is present at compile time), it transmits a reverse-DNS (PTR) query for each IP address revealed by an incoming ICMP time-exceeded response contemporaneously with the remaining probe traffic. By the time the trace completes, most or all hostnames have already been resolved, so lookups incur little or no additional time. The -Q flag reverts to the traditional synchronous getnameinfo(3) path, which resolves each hop in sequence after the trace completes. This flag is useful for debugging DNS issues or for environments where parallel DNS queries are undesirable. If LFT was built without c-ares, this flag is accepted but has no effect.

--help
    Display a brief usage summary and exit. Long-form option equivalents (e.g., --dport, --min-probes, --ignore-unreachables) are available for all short options and are documented in this manual page alongside their short counterparts.

Any hosts listed after these options and before the final target host will comprise a Loose Source and Record Route (LSRR). lft encodes the specified intermediate addresses into the IP options field of every probe, using option type 131 as defined in RFC 791 (the original IPv4 specification).

LSRR on the modern Internet. The original purpose of source routing was to allow a sender to specify the path a packet should take through the network, useful in early research networks for debugging routing policy and deliberately routing around link failures. However, source routing can be exploited to bypass access controls, conduct reflective attacks, and probe otherwise-isolated network segments. As a consequence, virtually all ISPs and enterprise network operators block or silently strip packets carrying source route options at network ingress. RFC 7126 (February 2014) formally codified this practice, recommending that routers SHOULD drop packets containing LSRR or SSRR IP options, and noting zero operational impact from doing so because no production traffic legitimately uses them.

Why LSRR is retained in lft. The feature remains for controlled network environments where intermediate devices are operator-managed and IP options processing is known to be enabled: lab networks, private AS testing, research testbeds, and similar settings. In such environments, specifying intermediate waypoints can verify specific forwarding paths that are otherwise difficult to isolate. On any public Internet path it will produce no additional hops in the output.

Caution: accidental LSRR activation. Because -p (ICMP probe mode) takes no argument, any extra token appearing between -p and the target is silently parsed as an LSRR intermediate hop rather than being flagged as an error. For example,

    lft -p 192.168.1.1 target.example.com

would add 192.168.1.1 as a source route waypoint and embed a 12-byte LSRR IP option in every probe, almost certainly producing no responses from any modern router. The trace will appear to run normally but all hops will be cloaked. Verify command syntax carefully when using ICMP mode.

EXAMPLES
A sample use and output might be:

    [edge.lax]$ lft -S 4.2.2.2
    Hop  LFT trace to vnsc-bak.sys.gtei.net (4.2.2.2):80/tcp
     1   ln-gateway.centergate.com (206.117.161.1) 0.5ms
     2   isi-acg.ln.net (130.152.136.1) 2.3ms
     3   isi-1-lngw2-atm.ln.net (130.152.180.21) 2.5ms
     4   gigabitethernet5-0.lsanca1-cr3.bbnplanet.net (4.24.4.249) 3.0ms
     5   p6-0.lsanca1-cr6.bbnplanet.net (4.24.4.2) 3.4ms
     6   p6-0.lsanca2-br1.bbnplanet.net (4.24.5.49) 3.3ms
     7   p15-0.snjpca1-br1.bbnplanet.net (4.24.5.58) 10.9ms
     8   so-3-0-0.mtvwca1-br1.bbnplanet.net (4.24.7.33) 11.1ms
     9   p7-0.mtvwca1-dc-dbe1.bbnplanet.net (4.24.9.166) 11.0ms
    10   vlan40.mtvwca1-dc1-dfa1-rc1.bbnplanet.net (128.11.193.67) 11.1ms
    **   [neglected] no reply packets received from TTLs 11 through 20
    **   [4.2-3 BSD bug] the next gateway may errantly reply with reused TTLs
    21   [target] vnsc-bak.sys.gtei.net (4.2.2.2) 11.2ms

The (-S) option was used to suppress the real-time status bar for clean output. LFT's "**" notifiers in between hops 10 and 21 represent additional useful information: the first is a "[neglected]" indicator that lets us know that none of the probes sent with the TTLs indicated elicited responses. This could be for a variety of reasons, but the cause of this specific occurrence is described in the next informative message which indicates that this is likely the result of a bug in the 4.[23] BSD network code (and its derivatives): BSD 4.x (x < 3) sends an unreachable message using whatever TTL remains in the original datagram. Since, for gateways, the remaining TTL is zero, the ICMP "time exceeded" is guaranteed to not make it back to us. LFT does its best to identify this condition rather than print lots and lots of hops that don't exist (trying to reach a high enough TTL).

Now, using the adaptive engine option:

    [edge.lax]$ lft -E -S 4.2.2.1
    Hop  LFT trace to vnsc-pri.sys.gtei.net (4.2.2.1):80/tcp
     1   ln-gateway.centergate.com (206.117.161.1) 0.5/0.5ms
     2   isi-acg.ln.net (130.152.136.1) 2.1/2.3ms
     3   isi-1-lngw2-atm.ln.net (130.152.180.21) 2.6/7.1ms
     4   gigabitethernet5-0.lsanca1-cr3.bbnplanet.net (4.24.4.249) 6.1/3.9ms
    **   [firewall] the next gateway may statefully inspect packets
     5   p0-0-0.lsanca1-csr1.bbnplanet.net (4.24.4.10) 155.4/3.7ms
     6   [target] vnsc-pri.sys.gtei.net (4.2.2.1) 22.6/3.7/*/*/*/*/*ms

In the scenario above, the adaptive engine was able to identify a stateful, packet-inspecting firewall in the path. Another example with more options:

    [edge.lax]$ lft -S -A -T -m 2 -d 80 -s 53 www.yahoo.com
    Hop  LFT trace to w9.scd.yahoo.com (66.218.71.88):80/tcp
     1   [226] ln-gateway.centergate.com (206.117.161.1)  1 ms
     2   [226] isi-acg.ln.net (130.152.136.1)  2 ms
     3   [226] isi-1-lngw2-atm.ln.net (130.152.180.21)  3 ms
     4   [1] gigether5-0.lsanca1-cr3.bbnplanet.net (4.24.4.249)  3 ms
     5   [1] p6-0.lsanca1-cr6.bbnplanet.net (4.24.4.2)  5 ms
     6   [1] p6-0.lsanca2-br1.bbnplanet.net (4.24.5.49)  3 ms
     7   [1] p1-0.lsanca2-cr2.bbnplanet.net (4.25.112.1)  3 ms
     8   [16852] pos4-0.core1.LosAngeles1.Level3.net (209.0.227.57)  3 ms
     9   [3356] so-4-0-0.mp1.LosAngeles1.Level3.net (209.247.10.193)  3 ms
    10   [3356] so-3-0-0.mp2.SanJose1.Level3.net (64.159.1.130)  11 ms
    11   [3356] gige10-0.ipcolo4.SanJose1.Level3.net (64.159.2.42)  11 ms
    12   [3356] cust-int.level3.net (64.152.81.62)  52 ms
    13   [10310] vl17.bas2.scd.yahoo.com (66.218.64.150)  53 ms
    14   [10310] w9.scd.yahoo.com (66.218.71.88) [target]  54 ms

    LFT's trace took 5.23 seconds.  Resolution required 3.58 seconds.

Note the -Ar above displays ASNs using the RADB as a whois source. A better option may have been to use the -A alone or perhaps -AC.

And why not request netblock lookups?

    [edge.lax]$ lft -S -N www.microsoft.com
    Hop  LFT trace to www.us.microsoft.com (207.46.197.113):80/tcp
     1   [LOS-NETTOS-BLK4] ln-gateway.centergate.com (206.117.161.1)  2 ms
     2   [LOS-NETTOS] isi-acg.ln.net (130.152.136.1)  3 ms
     3   [LOS-NETTOS] isi-1-lngw2-pos.ln.net (130.152.80.30)  5 ms
     4   [GNTY-4-0] gigether5-0.lsanca1-cr3.bbnplanet.net (4.24.4.249)  4 ms
     5   [GNTY-4-0] p6-0.lsanca1-cr6.bbnplanet.net (4.24.4.2)  3 ms
     6   [GNTY-4-0] p6-0.lsanca2-br1.bbnplanet.net (4.24.5.49)  3 ms
     7   [GNTY-4-0] p15-0.snjpca1-br1.bbnplanet.net (4.24.5.58)  10 ms
     8   [GNTY-4-0] p9-0.snjpca1-br2.bbnplanet.net (4.24.9.130)  11 ms
     9   [GNTY-4-0] so-1-0-0.sttlwa2-br1.bbnplanet.net (4.0.3.229)  27 ms
    10   [GNTY-4-0] so-0-0-0.sttlwa1-hcr1.bbnplanet.net (4.24.11.202)  28 ms
    11   [GNTY-4-0] so-7-0-0.sttlwa1-hcr2.bbnplanet.net (4.24.10.234)  28 ms
    12   [GNTY-4-0] p1-0.sttlwa1-cr2.bbnplanet.net (4.24.10.241)  29 ms
    13   [GNTY-4-0] p2-0.msseattle.bbnplanet.net (4.25.89.6)  32 ms
    14   [MICROSOFT-GLOBAL-NET] 207.46.154.9  32 ms
    15   [MICROSOFT-GLOBAL-NET] 207.46.155.17  33 ms
    16   [MICROSOFT-GLOBAL-NET] 207.46.129.51 [prohibited]  35 ms

TROUBLESHOOTING
If traces don't appear to go anywhere, there are a number of things to try. If you are receiving an error related to permissions, lft requires elevated privileges to open raw sockets and capture packets via pcap(3). On Linux, the preferred approach is to grant file capabilities rather than installing a setuid root binary:

    setcap cap_net_raw,cap_net_admin=eip /usr/sbin/lft

This requires the libcap2-bin package on Debian/Ubuntu or libcap on RHEL/Fedora. The make install target attempts this automatically and falls back to setuid root if setcap(8) is not available. On FreeBSD, lft must be installed setuid root.

On macOS, lft must be installed setuid root. This is because lft uses two separate privilege paths: pcap(3) (via /dev/bpf* devices) for capturing response packets, and a raw socket (SOCK_RAW) for sending probe packets. BPF device permissions (e.g., the ChmodBPF mechanism used by Wireshark) only cover the capture side — they do not grant the ability to create raw sockets, which on macOS requires root. Unlike Linux, macOS has no setcap(8) equivalent to selectively grant raw socket capability to a binary.

To install setuid root:

    sudo chown root lft && sudo chmod u+s lft

make install performs this step automatically when run as root. This is standard practice for network diagnostic tools on macOS; ping(8) and traceroute(8) ship setuid root for the same reason.

If you do not receive permissions-related errors, but traces still don't go anywhere, first activate verbose output by adding -VV to your command line options. Then, reading the verbose output, if you see trace probes going out, but no replies being detected (as indicated by "RCVD" tags), you may: Use the TCP basic (-b) method if you wish to use TCP probes and you fear NAT may be causing your trace to fail. Alternatively, select a different trace method and protocol such as UDP (-u) or ICMP (-p).

If you are attempting to use RFC 1393 (-P) and your trace is failing, this is likely because network equipment somewhere in the path does not conform to RFC 1393. Your only option is to select an alternative tracing method or protocol.

If you are attempting to utilize adaptive mode (-E/-e) and traces fail, first try enabling NAT compatibility using TCP basic (-b). If traces still fail, the most likely reason is a close-proximity stateful firewall in your network, which prevents this feature from working.

AUTHORS
Victor Oppleman, Eugene Antsilevitch, Sergey Kondryukov and other helpers around the world.

REPORTING BUGS
To report bugs, send e-mail to <lft@oppleman.com>

SEE ALSO
traceroute(8), netstat(1), whois(1), whob(8)

HISTORY
The lft command first appeared in 1998 as 'fft'. Renamed as a result of confusion with fast fourier transforms, lft stands for 'layer four traceroute.' Thanks also to Nils McCarthy for writing 'FFT', LFT's predecessor.