From f8fc8806401596b08779cf8c88da31408c9b0547 Mon Sep 17 00:00:00 2001 From: srdusr <99972264+srdusr@users.noreply.github.com> Date: Tue, 28 May 2024 01:55:00 +0200 Subject: Add ARP decoding and bring the TUI up to -c/-a parity ARP had zero treatment until now - its ethertype just fell through summarize_packet's "not IPv4/IPv6" branch, on traffic that appears on essentially every real LAN capture. Scoped to Ethernet/IPv4 addressing (the case that covers virtually all real ARP traffic), with tcpdump's own "who-has X tell Y" / "X is-at Y" phrasing rather than inventing new wording. Live-verified by flushing this machine's real gateway ARP entry and capturing the resulting request/reply on wlp1s0. TUI -c/-a were being parsed into RenderOptions but silently did nothing: run_tui()'s consumer thread had its own loop that never read them, unlike plain-text mode's render_packet(). Fixed to match, and caught a real bug while doing it - pushing up to two rows per packet (summary + reassembly line) against a single pop_front() would let the row deque grow past its cap under sustained -a activity; needed a while loop instead. Verified under tmux against the same split-segment HTTP scenario used to verify -a on the CLI and GUI. --- src/main.cpp | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/main.cpp b/src/main.cpp index 82b07a9..833af52 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -152,10 +152,25 @@ void run_tui(packeteer::CaptureSession& session, packeteer::CaptureQueue& queue, packet->ts_usec, bytes, packet->original_len); } + if (opts.verbose_checksums) { + std::string status = packeteer::checksum_status(bytes, opts.datalink); + if (!status.empty()) line += " " + status; + } + std::optional reassembled; + if (opts.reassembler) { + reassembled = packeteer::reassembled_http_status(bytes, opts.datalink, + *opts.reassembler); + } + { std::lock_guard lock(state_mutex); rows.push_back(std::move(line)); - if (rows.size() > kMaxRows) rows.pop_front(); + if (reassembled) rows.push_back(" [" + *reassembled + "]"); + // A while loop, not if: up to two rows can be pushed per + // packet now (the summary plus an optional reassembly + // line), so a single pop_front() would let the deque + // grow past kMaxRows under sustained -a activity. + while (rows.size() > kMaxRows) rows.pop_front(); ++packet_count; } screen.PostEvent(Event::Custom); @@ -275,13 +290,13 @@ void print_usage(const char* argv0) { "Options:\n" " -t, --tui Launch the interactive TUI instead of plain-text output\n" " -x Show a hex dump under each summary (plain-text mode only)\n" - " -c Show IPv4/TCP/UDP checksum validity (plain-text mode only).\n" + " -c Show IPv4/TCP/UDP checksum validity (plain-text and TUI).\n" " Off by default: checksum offload means many outbound and\n" " loopback packets show as invalid even when nothing is\n" " actually wrong - the NIC computes the real checksum in\n" " hardware after most capture points already saw the packet.\n" " -a Reassemble TCP streams and re-run HTTP parsing on the\n" - " joined bytes (plain-text mode only), catching a\n" + " joined bytes (plain-text and TUI), catching a\n" " request/response split across multiple segments that\n" " single-packet HTTP dissection alone would miss. In-order\n" " segments only - out-of-order/retransmitted segments are\n" -- cgit v1.2.3