blob: 80bd1a7edef2bc360b10f7ea5ecef2cbe084ea57 [file] [log] [blame]
/*
*
* 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 "RecordData.h"
#include <inet/arpa-inet-compatibility.h>
#include <stdio.h>
namespace mdns {
namespace Minimal {
bool ParseTxtRecord(const BytesRange & data, TxtRecordDelegate * callback)
{
// FORMAT:
// length-prefixed strings of the form "foo=bar" where = may be missing
const uint8_t * pos = data.Start();
while (data.Contains(pos))
{
uint8_t length = *pos;
if (!data.Contains(pos + length))
{
return false;
}
// name=value string of size length
const uint8_t * equalPos = pos + 1;
while (((equalPos - pos) < length) && (*equalPos != '='))
{
equalPos++;
}
if (pos + length == equalPos && *equalPos == '=')
{
// If there is an '=' sign with an empty value, just ignore it and position the end cursor directly onto
// the position of the '='
callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange());
}
else if (pos + length == equalPos && *equalPos != '=')
{
callback->OnRecord(BytesRange(pos + 1, equalPos + 1), BytesRange());
}
else
{
callback->OnRecord(BytesRange(pos + 1, equalPos), BytesRange(equalPos + 1, pos + 1 + length));
}
pos += 1 + length;
}
return pos == data.End();
}
bool SrvRecord::Parse(const BytesRange & data, const BytesRange & packet)
{
// FORMAT:
// - priority
// - weight
// - port
// - target
if (data.Size() < 7)
{
return false;
}
const uint8_t * p = data.Start();
mPriority = chip::Encoding::BigEndian::Read16(p);
mWeight = chip::Encoding::BigEndian::Read16(p);
mPort = chip::Encoding::BigEndian::Read16(p);
mName = SerializedQNameIterator(packet, p);
return true;
}
bool ParseARecord(const BytesRange & data, chip::Inet::IPAddress * addr)
{
#if INET_CONFIG_ENABLE_IPV4
if (data.Size() != 4)
{
return false;
}
addr->Addr[0] = 0;
addr->Addr[1] = 0;
addr->Addr[2] = htonl(0xFFFF);
addr->Addr[3] = htonl(chip::Encoding::BigEndian::Get32(data.Start()));
return true;
#else
// IPV4 support is disabled: IPAddress should never get IPv4 values.
return false;
#endif
}
bool ParseAAAARecord(const BytesRange & data, chip::Inet::IPAddress * addr)
{
if (data.Size() != 16)
{
return false;
}
const uint8_t * p = data.Start();
chip::Inet::IPAddress::ReadAddress(p, *addr);
return true;
}
bool ParsePtrRecord(const BytesRange & data, const BytesRange & packet, SerializedQNameIterator * name)
{
if (data.Size() < 1)
{
return false;
}
*name = SerializedQNameIterator(packet, data.Start());
return true;
}
} // namespace Minimal
} // namespace mdns