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 51 : bool ParseTxtRecord(const BytesRange & data, TxtRecordDelegate * callback)
27 : {
28 : // FORMAT:
29 : // length-prefixed strings of the form "foo=bar" where = may be missing
30 51 : const uint8_t * pos = data.Start();
31 :
32 299 : while (data.Contains(pos))
33 : {
34 248 : uint8_t length = *pos;
35 :
36 248 : if (!data.Contains(pos + length))
37 : {
38 0 : return false;
39 : }
40 :
41 : // name=value string of size length
42 248 : const uint8_t * equalPos = pos + 1;
43 743 : while (((equalPos - pos) < length) && (*equalPos != '='))
44 : {
45 495 : equalPos++;
46 : }
47 :
48 248 : 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 29 : callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange());
53 : }
54 219 : else if (pos + length == equalPos && *equalPos != '=')
55 : {
56 5 : callback->OnRecord(BytesRange(pos + 1, equalPos + 1), BytesRange());
57 : }
58 : else
59 : {
60 214 : callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange(equalPos + 1, pos + 1 + length));
61 : }
62 :
63 248 : pos += 1 + length;
64 : }
65 :
66 51 : return pos == data.End();
67 : }
68 :
69 45 : bool SrvRecord::Parse(const BytesRange & data, const BytesRange & packet)
70 : {
71 : // FORMAT:
72 : // - priority
73 : // - weight
74 : // - port
75 : // - target
76 45 : if (data.Size() < 7)
77 : {
78 0 : return false;
79 : }
80 :
81 45 : const uint8_t * p = data.Start();
82 :
83 45 : mPriority = chip::Encoding::BigEndian::Read16(p);
84 45 : mWeight = chip::Encoding::BigEndian::Read16(p);
85 45 : mPort = chip::Encoding::BigEndian::Read16(p);
86 45 : mName = SerializedQNameIterator(packet, p);
87 :
88 45 : return true;
89 : }
90 :
91 13 : bool ParseARecord(const BytesRange & data, chip::Inet::IPAddress * addr)
92 : {
93 : #if INET_CONFIG_ENABLE_IPV4
94 13 : if (data.Size() != 4)
95 : {
96 0 : return false;
97 : }
98 :
99 13 : addr->Addr[0] = 0;
100 13 : addr->Addr[1] = 0;
101 13 : addr->Addr[2] = htonl(0xFFFF);
102 13 : addr->Addr[3] = htonl(chip::Encoding::BigEndian::Get32(data.Start()));
103 :
104 13 : return true;
105 : #else
106 : // IPV4 support is disabled: IPAddress should never get IPv4 values.
107 : return false;
108 : #endif
109 : }
110 :
111 16 : bool ParseAAAARecord(const BytesRange & data, chip::Inet::IPAddress * addr)
112 : {
113 16 : if (data.Size() != 16)
114 : {
115 0 : return false;
116 : }
117 16 : const uint8_t * p = data.Start();
118 16 : chip::Inet::IPAddress::ReadAddress(p, *addr);
119 16 : 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
|