Line data Source code
1 : /* 2 : * 3 : * Copyright (c) 2020 Project CHIP Authors 4 : * 5 : * Licensed under the Apache License, Version 2.0 (the "License"); 6 : * you may not use this file except in compliance with the License. 7 : * You may obtain a copy of the License at 8 : * 9 : * http://www.apache.org/licenses/LICENSE-2.0 10 : * 11 : * Unless required by applicable law or agreed to in writing, software 12 : * distributed under the License is distributed on an "AS IS" BASIS, 13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 : * See the License for the specific language governing permissions and 15 : * limitations under the License. 16 : */ 17 : 18 : #include "RecordData.h" 19 : 20 : #include <inet/arpa-inet-compatibility.h> 21 : #include <stdio.h> 22 : 23 : namespace mdns { 24 : namespace Minimal { 25 : 26 91 : bool ParseTxtRecord(const BytesRange & data, TxtRecordDelegate * callback) 27 : { 28 : // FORMAT: 29 : // length-prefixed strings of the form "foo=bar" where = may be missing 30 91 : const uint8_t * pos = data.Start(); 31 : 32 532 : while (data.Contains(pos)) 33 : { 34 441 : uint8_t length = *pos; 35 : 36 441 : if (!data.Contains(pos + length)) 37 : { 38 0 : return false; 39 : } 40 : 41 : // name=value string of size length 42 441 : const uint8_t * equalPos = pos + 1; 43 1289 : while (((equalPos - pos) < length) && (*equalPos != '=')) 44 : { 45 848 : equalPos++; 46 : } 47 : 48 441 : if (pos + length == equalPos && *equalPos == '=') 49 : { 50 : // If there is an '=' sign with an empty value, just ignore it and position the end cursor directly onto 51 : // the position of the '=' 52 69 : callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange()); 53 : } 54 372 : else if (pos + length == equalPos && *equalPos != '=') 55 : { 56 5 : callback->OnRecord(BytesRange(pos + 1, equalPos + 1), BytesRange()); 57 : } 58 : else 59 : { 60 367 : callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange(equalPos + 1, pos + 1 + length)); 61 : } 62 : 63 441 : pos += 1 + length; 64 : } 65 : 66 91 : return pos == data.End(); 67 : } 68 : 69 65 : bool SrvRecord::Parse(const BytesRange & data, const BytesRange & packet) 70 : { 71 : // FORMAT: 72 : // - priority 73 : // - weight 74 : // - port 75 : // - target 76 65 : if (data.Size() < 7) 77 : { 78 0 : return false; 79 : } 80 : 81 65 : const uint8_t * p = data.Start(); 82 : 83 65 : mPriority = chip::Encoding::BigEndian::Read16(p); 84 65 : mWeight = chip::Encoding::BigEndian::Read16(p); 85 65 : mPort = chip::Encoding::BigEndian::Read16(p); 86 65 : mName = SerializedQNameIterator(packet, p); 87 : 88 65 : return true; 89 : } 90 : 91 33 : bool ParseARecord(const BytesRange & data, chip::Inet::IPAddress * addr) 92 : { 93 : #if INET_CONFIG_ENABLE_IPV4 94 33 : if (data.Size() != 4) 95 : { 96 0 : return false; 97 : } 98 : 99 33 : addr->Addr[0] = 0; 100 33 : addr->Addr[1] = 0; 101 33 : addr->Addr[2] = htonl(0xFFFF); 102 33 : addr->Addr[3] = htonl(chip::Encoding::BigEndian::Get32(data.Start())); 103 : 104 33 : return true; 105 : #else 106 : // IPV4 support is disabled: IPAddress should never get IPv4 values. 107 : return false; 108 : #endif 109 : } 110 : 111 36 : bool ParseAAAARecord(const BytesRange & data, chip::Inet::IPAddress * addr) 112 : { 113 36 : if (data.Size() != 16) 114 : { 115 0 : return false; 116 : } 117 36 : const uint8_t * p = data.Start(); 118 36 : chip::Inet::IPAddress::ReadAddress(p, *addr); 119 36 : return true; 120 : } 121 : 122 51 : bool ParsePtrRecord(const BytesRange & data, const BytesRange & packet, SerializedQNameIterator * name) 123 : { 124 51 : if (data.Size() < 1) 125 : { 126 0 : return false; 127 : } 128 : 129 51 : *name = SerializedQNameIterator(packet, data.Start()); 130 : 131 51 : return true; 132 : } 133 : 134 : } // namespace Minimal 135 : } // namespace mdns