srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/include/wireframe/l7/mdns.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'include/wireframe/l7/mdns.hpp')
-rw-r--r--include/wireframe/l7/mdns.hpp44
1 files changed, 44 insertions, 0 deletions
diff --git a/include/wireframe/l7/mdns.hpp b/include/wireframe/l7/mdns.hpp
new file mode 100644
index 0000000..887d811
--- /dev/null
+++ b/include/wireframe/l7/mdns.hpp
@@ -0,0 +1,44 @@
+#pragma once
+
+#include <cstdint>
+#include <optional>
+#include <span>
+#include <string>
+
+#include "wireframe/l7/dissector.hpp"
+#include "wireframe/l7/dns.hpp"
+
+// mDNS (RFC 6762) reuses DNS's exact wire format - same header layout,
+// same question/name encoding - just over a different port (5353,
+// usually to/from the multicast address 224.0.0.251) and typically
+// with many questions/answers per packet instead of DNS's usual one.
+// parse_dns() already only looks at the first question, which is true
+// here too; the only real difference worth a label is which protocol
+// this traffic actually is, so real-world capture output doesn't read
+// "DNS" for traffic that never touched a resolver.
+namespace wireframe::net {
+
+inline constexpr std::uint16_t kMdnsPort = 5353;
+
+class MdnsDissector : public L7Dissector {
+public:
+ std::uint16_t port() const override { return kMdnsPort; }
+
+ std::optional<std::string> summarize(std::span<const unsigned char> payload) const override {
+ auto msg = parse_dns(payload);
+ if (!msg) return std::nullopt;
+
+ // No id= field here unlike DnsDissector's summary: RFC 6762
+ // 18.1 has multicast queries send it as zero, so printing it
+ // would just be "id=0" noise on real traffic.
+ std::string out = "mDNS ";
+ out += msg->header.is_response ? "response" : "query";
+ if (msg->header.is_response) out += " ancount=" + std::to_string(msg->header.ancount);
+ if (msg->question) {
+ out += " " + msg->question->name + " type=" + std::to_string(msg->question->qtype);
+ }
+ return out;
+ }
+};
+
+} // namespace wireframe::net