1 /* 2 * Copyright (C) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef MDNS_PACKET_PARSER_H 17 #define MDNS_PACKET_PARSER_H 18 19 #include <any> 20 #include <string> 21 #include <string_view> 22 #include <vector> 23 24 #include <netinet/in.h> 25 26 #include "mdns_common.h" 27 28 namespace OHOS { 29 namespace NetManagerStandard { 30 31 namespace DNSProto { 32 33 constexpr uint16_t HEADER_FLAGS_QR_MASK = 0x8000; 34 constexpr uint16_t HEADER_FLAGS_OPCODE_MASK = 0x7800; 35 constexpr uint16_t HEADER_FLAGS_AA_MASK = 0x0400; 36 constexpr uint16_t HEADER_FLAGS_TC_MASK = 0x0200; 37 constexpr uint16_t HEADER_FLAGS_RD_MASK = 0x0100; 38 constexpr uint16_t HEADER_FLAGS_RA_MASK = 0x0080; 39 constexpr uint16_t HEADER_FLAGS_Z_MASK = 0x0040; 40 constexpr uint16_t HEADER_FLAGS_AD_MASK = 0x0020; 41 constexpr uint16_t HEADER_FLAGS_CD_MASK = 0x0010; 42 constexpr uint16_t HEADER_FLAGS_RCODE_MASK = 0x000f; 43 44 constexpr uint16_t HEADER_FLAGS_QR_OFFSET = 15; 45 constexpr uint16_t HEADER_FLAGS_OPCODE_OFFSET = 11; 46 constexpr uint16_t HEADER_FLAGS_AA_OFFSET = 10; 47 constexpr uint16_t HEADER_FLAGS_TC_OFFSET = 9; 48 constexpr uint16_t HEADER_FLAGS_RD_OFFSET = 8; 49 constexpr uint16_t HEADER_FLAGS_RA_OFFSET = 7; 50 constexpr uint16_t HEADER_FLAGS_Z_OFFSET = 6; 51 constexpr uint16_t HEADER_FLAGS_AD_OFFSET = 5; 52 constexpr uint16_t HEADER_FLAGS_CD_OFFSET = 4; 53 constexpr uint16_t HEADER_FLAGS_RCODE_OFFSET = 0; 54 55 // QR = 1, AA = 1 56 static constexpr uint16_t MDNS_ANSWER_FLAGS = 0x8400; 57 58 // DNS Header format (https://www.rfc-editor.org/rfc/rfc1035#section-4.1.1) 59 // 1 1 1 1 1 1 60 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 61 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 62 // | ID | 63 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 64 // |QR| OpCode |AA|TC|RD|RA| Z|AD|CD| RCODE | 65 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 66 // | QDCOUNT/ZOCOUNT | 67 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 68 // | ANCOUNT/PRCOUNT | 69 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 70 // | NSCOUNT/UPCOUNT | 71 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 72 // | ARCOUNT | 73 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 74 struct Header { 75 uint16_t id = 0x0; 76 uint16_t flags = 0x0; 77 uint16_t qdcount = 0x0; 78 uint16_t ancount = 0x0; 79 uint16_t nscount = 0x0; 80 uint16_t arcount = 0x0; 81 }; 82 83 // RR Type (https://www.rfc-editor.org/rfc/rfc1035#section-3.2.2) 84 enum RRType { 85 RRTYPE_IGNORE = 0, 86 RRTYPE_A = 1, 87 RRTYPE_PTR = 12, 88 RRTYPE_TXT = 16, 89 RRTYPE_AAAA = 28, 90 RRTYPE_SRV = 33, 91 RRTYPE_ANY = 255 92 }; 93 94 // RR Class (https://www.rfc-editor.org/rfc/rfc1035#section-3.2.4) 95 enum RRClass { 96 RRCLASS_IN = 1, 97 RRCLASS_ANY = 255 98 }; 99 100 // DNS Question format (https://www.rfc-editor.org/rfc/rfc1035#section-4.1.2) 101 // 1 1 1 1 1 1 102 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 103 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 104 // | | 105 // / QNAME / 106 // / / 107 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 108 // | QTYPE | 109 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 110 // | QCLASS | 111 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 112 struct Question { 113 std::string name; 114 uint16_t qtype; 115 uint16_t qclass; 116 }; 117 118 // DNS SRV RR format (https://www.rfc-editor.org/rfc/rfc2782) 119 struct RDataSrv { 120 uint16_t priority; 121 uint16_t weight; 122 uint16_t port; 123 std::string name; 124 }; 125 126 // DNS RR format (https://www.rfc-editor.org/rfc/rfc1035#section-3.2.1) 127 // 1 1 1 1 1 1 128 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 129 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 130 // | | 131 // / / 132 // / NAME / 133 // | | 134 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 135 // | TYPE | 136 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 137 // | CLASS | 138 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 139 // | TTL | 140 // | | 141 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 142 // | RDLENGTH | 143 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| 144 // / RDATA / 145 // / / 146 // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 147 struct ResourceRecord { 148 std::string name; 149 uint16_t rtype; 150 uint16_t rclass; 151 uint32_t ttl; 152 uint16_t length; 153 std::any rdata; 154 }; 155 156 // Messages format (https://www.rfc-editor.org/rfc/rfc1035#section-4.1) 157 struct Message { 158 Header header; 159 std::vector<Question> questions; 160 std::vector<ResourceRecord> answers; 161 std::vector<ResourceRecord> authorities; 162 std::vector<ResourceRecord> additional; 163 }; 164 165 } // namespace DNSProto 166 167 using MDnsMessage = DNSProto::Message; 168 169 // Parse mDNS Message from UDP payload or serialize DNS Message to bytes 170 // This parser could record error location 171 class MDnsPayloadParser { 172 public: 173 enum { 174 PARSE_OK = 0, 175 PARSE_ERROR = 0xffff, 176 PARSE_ERROR_BAD_SIZE = 0x1, 177 PARSE_ERROR_BAD_STR = 0x2, 178 PARSE_ERROR_BAD_STRPTR = 0x4, 179 PARSE_WARNING = 0xffff0000, 180 PARSE_WARNING_BAD_ENTRY_SIZE = 0x40000000, 181 PARSE_WARNING_BAD_RRTYPE = 0x80000000, 182 }; 183 184 MDnsPayloadParser() = default; 185 ~MDnsPayloadParser() = default; 186 187 /** 188 * parse function 189 * 190 * @param udp payload as bytes 191 * @return dns message struct 192 */ 193 MDnsMessage FromBytes(const MDnsPayload &payload); 194 195 /** 196 * parse function 197 * 198 * @param dns message struct 199 * @return dns message as bytes for transmission 200 */ 201 MDnsPayload ToBytes(const MDnsMessage &msg); 202 203 /** 204 * get parse error function 205 * @return all error in uint32, use PARSE_ERROR_* to extract 206 */ 207 uint32_t GetError() const; 208 209 private: 210 const uint8_t *Parse(const uint8_t *begin, const MDnsPayload &payload, MDnsMessage &msg); 211 const uint8_t *ParseHeader(const uint8_t *begin, const MDnsPayload &payload, DNSProto::Header &header); 212 const uint8_t *ParseQuestion(const uint8_t *begin, const MDnsPayload &payload, 213 std::vector<DNSProto::Question> &questions); 214 const uint8_t *ParseRR(const uint8_t *begin, const MDnsPayload &payload, 215 std::vector<DNSProto::ResourceRecord> &answers); 216 const uint8_t *ParseRData(const uint8_t *begin, const MDnsPayload &payload, int type, int length, std::any &data); 217 const uint8_t *ParseSrv(const uint8_t *begin, const MDnsPayload &payload, std::any &data); 218 const uint8_t *ParseTxt(const uint8_t *begin, const MDnsPayload &payload, int length, std::any &data); 219 220 // Read https://www.rfc-editor.org/rfc/rfc1035#section-4.1.4 221 const uint8_t *ParseDnsString(const uint8_t *begin, const MDnsPayload &payload, std::string &str); 222 223 void Serialize(const MDnsMessage &msg, MDnsPayload &payload, MDnsPayload *cachedPayload, 224 std::map<std::string, uint16_t> &strCacheMap); 225 void SerializeHeader(const DNSProto::Header &header, const MDnsMessage &msg, MDnsPayload &payload); 226 void SerializeQuestion(const DNSProto::Question &question, MDnsPayload &payload, MDnsPayload *cachedPayload, 227 std::map<std::string, uint16_t> &strCacheMap); 228 void SerializeRR(const DNSProto::ResourceRecord &rr, MDnsPayload &payload, MDnsPayload *cachedPayload, 229 std::map<std::string, uint16_t> &strCacheMap); 230 void SerializeRData(const std::any &rdata, MDnsPayload &payload, MDnsPayload *cachedPayload, 231 std::map<std::string, uint16_t> &strCacheMap); 232 void SerializeDnsString(const std::string &str, MDnsPayload &payload, MDnsPayload *cachedPayload, 233 std::map<std::string, uint16_t> &strCacheMap); 234 235 uint32_t errorFlags_ = 0; 236 const uint8_t *pos_ = nullptr; 237 }; 238 239 } // namespace NetManagerStandard 240 } // namespace OHOS 241 #endif /* MDNS_PACKET_PARSER_H */ 242