diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 105 |
1 files changed, 8 insertions, 97 deletions
diff --git a/src/main.cpp b/src/main.cpp index 31fca73..72dd267 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -48,12 +48,8 @@ #include <ftxui/dom/elements.hpp> #include "wireframe/capture_session.hpp" -#include "wireframe/l7/http.hpp" -#include "wireframe/net/checksum.hpp" -#include "wireframe/net/ethernet.hpp" -#include "wireframe/net/ipv4.hpp" -#include "wireframe/net/tcp.hpp" #include "wireframe/net/tcp_reassembly.hpp" +#include "wireframe/packet_diagnostics.hpp" #include "wireframe/search.hpp" #include "wireframe/summarize.hpp" @@ -72,95 +68,6 @@ void hex_dump(std::span<const unsigned char> bytes) { std::printf("\n"); } -// -c only: checksum validation isn't part of summarize_packet()'s -// shared output (see wireframe/net/checksum.hpp for why - checksum -// offload makes it noise, not signal, on most of the interfaces this -// project has actually been tested against). IPv4 only for now; this -// does its own minimal walk down to the IP/TCP/UDP byte spans the -// checksum functions need, reusing the existing decoders rather than -// duplicating their parsing logic. -std::string checksum_status(std::span<const unsigned char> bytes, int datalink) { - std::span<const unsigned char> ip_bytes; - if (datalink == DLT_RAW) { - ip_bytes = bytes; - } else { - auto eth = wireframe::net::parse_ethernet(bytes); - if (!eth || eth->header.ethertype != wireframe::net::kEthertypeIPv4) return ""; - ip_bytes = eth->payload; - } - if (ip_bytes.empty() || (ip_bytes[0] >> 4) != 4) return ""; // only IPv4 checksums, for now - - auto ip = wireframe::net::parse_ipv4(ip_bytes); - if (!ip) return ""; - - std::size_t header_len = static_cast<std::size_t>(ip->header.ihl) * 4; - std::string out = " checksums: IP="; - out += wireframe::net::verify_ipv4_checksum(ip_bytes.first(header_len)) ? "ok" : "BAD"; - - using wireframe::net::ChecksumResult; - if (ip->header.protocol == wireframe::net::kProtoTcp) { - auto result = - wireframe::net::verify_tcp_checksum_ipv4(ip->header.src, ip->header.dst, ip->payload); - out += result == ChecksumResult::kValid ? " TCP=ok" : " TCP=BAD"; - } else if (ip->header.protocol == wireframe::net::kProtoUdp) { - auto result = - wireframe::net::verify_udp_checksum_ipv4(ip->header.src, ip->header.dst, ip->payload); - out += result == ChecksumResult::kValid ? " UDP=ok" - : result == ChecksumResult::kNotPresent ? " UDP=none" - : " UDP=BAD"; - } - return out; -} - -// -a only: TCP stream reassembly (wireframe/net/tcp_reassembly.hpp), -// re-run through the same HTTP dissector summarize_packet() already -// uses for a single segment - reassembly only helps when a message is -// actually split across packets, and HTTP is the L7 dissector in this -// project that's structured around lines/headers rather than one fixed -// datagram (DNS/TLS ClientHello are each their own single UDP datagram -// or first TCP segment already). Printed as its own line rather than -// folded into the per-packet summary: it reflects accumulated flow -// state, not just this one packet. In-order-only reassembly (see the -// header's own comment) means this can legitimately fire again on a -// later packet of the same request with an unchanged result once the -// headers are already complete - an honest simplification, not -// deduplicated further. -std::optional<std::string> reassembled_http_status(std::span<const unsigned char> bytes, - int datalink, - wireframe::net::TcpReassembler& reassembler) { - std::span<const unsigned char> ip_bytes; - if (datalink == DLT_RAW) { - ip_bytes = bytes; - } else { - auto eth = wireframe::net::parse_ethernet(bytes); - if (!eth || eth->header.ethertype != wireframe::net::kEthertypeIPv4) return std::nullopt; - ip_bytes = eth->payload; - } - if (ip_bytes.empty() || (ip_bytes[0] >> 4) != 4) return std::nullopt; // IPv4 only, for now - - auto ip = wireframe::net::parse_ipv4(ip_bytes); - if (!ip || ip->header.protocol != wireframe::net::kProtoTcp) return std::nullopt; - - auto tcp = wireframe::net::parse_tcp(ip->payload); - if (!tcp) return std::nullopt; - - auto reassembled = reassembler.process_segment(ip->header.src, tcp->header.src_port, - ip->header.dst, tcp->header.dst_port, - tcp->header.seq, tcp->header.flags, - tcp->payload); - if (!reassembled) return std::nullopt; - - auto http = wireframe::net::parse_http(*reassembled); - if (!http) return std::nullopt; - - std::string out = " [reassembled "; - out += http->is_request ? "request] " : "response] "; - out += http->method_or_version + " " + http->target_or_status; - if (http->host) out += " Host: " + *http->host; - out += " (" + std::to_string(reassembled->size()) + " bytes so far)"; - return out; -} - struct RenderOptions { bool verbose_hex; bool verbose_checksums; @@ -185,11 +92,15 @@ void render_packet(const wireframe::CapturedPacket& packet, const RenderOptions& if (!wireframe::matches_search(line, opts.search_term)) return; - if (opts.verbose_checksums) line += checksum_status(bytes, opts.datalink); + if (opts.verbose_checksums) { + std::string status = wireframe::checksum_status(bytes, opts.datalink); + if (!status.empty()) line += " " + status; + } std::printf("%s\n", line.c_str()); if (opts.reassembler) { - if (auto status = reassembled_http_status(bytes, opts.datalink, *opts.reassembler)) { - std::printf("%s\n", status->c_str()); + if (auto status = wireframe::reassembled_http_status(bytes, opts.datalink, + *opts.reassembler)) { + std::printf(" [%s]\n", status->c_str()); } } if (opts.verbose_hex) hex_dump(bytes); |