/* * * Copyright (c) 2020 Project CHIP Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "PacketReporter.h" #include #include #include #include namespace MdnsExample { namespace { const char * ToString(mdns::Minimal::QType qtype) { static char buff[32]; switch (qtype) { case mdns::Minimal::QType::A: return "A"; case mdns::Minimal::QType::NS: return "NS"; case mdns::Minimal::QType::CNAME: return "CNAME"; case mdns::Minimal::QType::SOA: return "SOA"; case mdns::Minimal::QType::WKS: return "WKS"; case mdns::Minimal::QType::PTR: return "PTR"; case mdns::Minimal::QType::MX: return "MX"; case mdns::Minimal::QType::SRV: return "SRV"; case mdns::Minimal::QType::AAAA: return "AAAA"; case mdns::Minimal::QType::ANY: return "ANY"; case mdns::Minimal::QType::TXT: return "TXT"; default: sprintf(buff, "UNKNOWN (%d)!!", static_cast(qtype)); return buff; } } const char * ToString(mdns::Minimal::QClass qclass) { static char buff[32]; switch (qclass) { case mdns::Minimal::QClass::IN_UNICAST: return "IN(UNICAST)"; case mdns::Minimal::QClass::IN: return "IN"; default: sprintf(buff, "UNKNOWN (%d)!!", static_cast(qclass)); return buff; } } const char * ToString(mdns::Minimal::ResourceType type) { static char buff[32]; switch (type) { case mdns::Minimal::ResourceType::kAnswer: return "ANSWER"; case mdns::Minimal::ResourceType::kAdditional: return "ADDITIONAL"; case mdns::Minimal::ResourceType::kAuthority: return "AUTHORITY"; default: sprintf(buff, "UNKNOWN (%d)!!", static_cast(type)); return buff; } } class TxtReport : public mdns::Minimal::TxtRecordDelegate { public: TxtReport(const char * prefix) : mPrefix(prefix) {} void OnRecord(const mdns::Minimal::BytesRange & name, const mdns::Minimal::BytesRange & value) override { std::string sname(reinterpret_cast(name.Start()), name.Size()); std::string svalue(reinterpret_cast(value.Start()), value.Size()); printf("%s TXT: '%s' = '%s'\n", mPrefix, sname.c_str(), svalue.c_str()); } private: const char * mPrefix; }; void PrintQName(mdns::Minimal::SerializedQNameIterator it) { while (it.Next()) { printf("%s.", it.Value()); } if (!it.IsValid()) { printf(" (INVALID!)"); } printf("\n"); } } // namespace void PacketReporter::OnHeader(mdns::Minimal::ConstHeaderRef & header) { printf("%s%s %d (%d, %d, %d, %d):\n", mPrefix, header.GetFlags().IsQuery() ? "QUERY" : "REPLY", header.GetMessageId(), header.GetQueryCount(), header.GetAnswerCount(), header.GetAuthorityCount(), header.GetAdditionalCount()); } void PacketReporter::OnQuery(const mdns::Minimal::QueryData & data) { printf("%s QUERY %s/%s%s: ", mPrefix, ToString(data.GetType()), ToString(data.GetClass()), data.RequestedUnicastAnswer() ? " UNICAST" : ""); PrintQName(data.GetName()); } void PacketReporter::OnResource(mdns::Minimal::ResourceType type, const mdns::Minimal::ResourceData & data) { printf("%s %s %s/%s ttl %ld: ", mPrefix, ToString(type), ToString(data.GetType()), ToString(data.GetClass()), static_cast(data.GetTtlSeconds())); PrintQName(data.GetName()); if (data.GetType() == mdns::Minimal::QType::TXT) { TxtReport txtReport(mPrefix); if (!mdns::Minimal::ParseTxtRecord(data.GetData(), &txtReport)) { printf("FAILED TO PARSE TXT RECORD\n"); } } else if (data.GetType() == mdns::Minimal::QType::SRV) { mdns::Minimal::SrvRecord srv; if (!srv.Parse(data.GetData(), mPacketRange)) { printf("Failed to parse SRV record!!!!"); } else { printf("%s SRV on port %d, priority %d, weight %d: ", mPrefix, srv.GetPort(), srv.GetPriority(), srv.GetWeight()); PrintQName(srv.GetName()); } } else if (data.GetType() == mdns::Minimal::QType::A) { chip::Inet::IPAddress addr; if (!mdns::Minimal::ParseARecord(data.GetData(), &addr)) { printf("FAILED TO PARSE A RECORD\n"); } else { char buff[128]; printf("%s IP: %s\n", mPrefix, addr.ToString(buff, sizeof(buff))); } } else if (data.GetType() == mdns::Minimal::QType::AAAA) { chip::Inet::IPAddress addr; if (!mdns::Minimal::ParseAAAARecord(data.GetData(), &addr)) { printf("FAILED TO PARSE AAAA RECORD\n"); } else { char buff[128]; printf("%s IP: %s\n", mPrefix, addr.ToString(buff, sizeof(buff))); } } else if (data.GetType() == mdns::Minimal::QType::PTR) { mdns::Minimal::SerializedQNameIterator name; if (!mdns::Minimal::ParsePtrRecord(data.GetData(), mPacketRange, &name)) { printf("FAILED TO PARSE AAAA RECORD\n"); } else { printf("%s PTR: ", mPrefix); PrintQName(name); } } else { // Unknown packet, just print data size. printf("%s Data size: %ld\n", mPrefix, static_cast(data.GetData().Size())); } } } // namespace MdnsExample