#include #include #include "packeteer/l7/ntp.hpp" using namespace packeteer::net; namespace { std::vector ntp_client_request() { std::vector bytes(48, 0); bytes[0] = (4 << 3) | 3; // version 4, mode 3 (client) bytes[1] = 0; // stratum: not applicable on a client request return bytes; } std::vector ntp_server_reply() { std::vector bytes(48, 0); bytes[0] = (4 << 3) | 4; // version 4, mode 4 (server) bytes[1] = 2; // stratum 2 return bytes; } } // namespace TEST_CASE("parse_ntp decodes a client request") { auto ntp = parse_ntp(ntp_client_request()); REQUIRE(ntp.has_value()); CHECK(ntp->version == 4); CHECK(ntp->mode == 3); } TEST_CASE("parse_ntp decodes a server reply with its stratum") { auto ntp = parse_ntp(ntp_server_reply()); REQUIRE(ntp.has_value()); CHECK(ntp->mode == 4); CHECK(ntp->stratum == 2); } TEST_CASE("parse_ntp rejects a payload shorter than the fixed header") { std::vector bytes(20, 0); CHECK_FALSE(parse_ntp(bytes).has_value()); } TEST_CASE("NtpDissector claims port 123 and includes stratum for client/server modes") { NtpDissector dissector; CHECK(dissector.port() == kNtpPort); auto summary = dissector.summarize(ntp_server_reply()); REQUIRE(summary.has_value()); CHECK(*summary == "NTP v4 server stratum=2"); } TEST_CASE("NtpDissector omits stratum for non-client/server modes") { NtpDissector dissector; std::vector bytes(48, 0); bytes[0] = (4 << 3) | 5; // mode 5: broadcast bytes[1] = 1; auto summary = dissector.summarize(bytes); REQUIRE(summary.has_value()); CHECK(summary->find("stratum") == std::string::npos); }