| /* |
| * |
| * 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 <memory> |
| #include <stdio.h> |
| #include <string> |
| |
| #include <lib/dnssd/minimal_mdns/RecordData.h> |
| |
| 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<int>(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<int>(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<int>(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<const char *>(name.Start()), name.Size()); |
| std::string svalue(reinterpret_cast<const char *>(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<long>(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<long>(data.GetData().Size())); |
| } |
| } |
| |
| } // namespace MdnsExample |