Matter SDK Coverage Report
Current view: top level - lib/dnssd/minimal_mdns - Parser.cpp (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 77.0 % 74 57
Test Date: 2025-01-17 19:00:11 Functions: 100.0 % 4 4

            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 "Parser.h"
      19              : 
      20              : #include "Query.h"
      21              : 
      22              : #include <stdio.h>
      23              : 
      24              : namespace mdns {
      25              : namespace Minimal {
      26              : 
      27           56 : bool QueryData::Parse(const BytesRange & validData, const uint8_t ** start)
      28              : {
      29              :     // Structure is:
      30              :     //    QNAME
      31              :     //    TYPE
      32              :     //    CLASS (plus a flag for unicast)
      33              : 
      34           56 :     if (!validData.Contains(*start))
      35              :     {
      36            0 :         return false;
      37              :     }
      38              : 
      39           56 :     const uint8_t * nameEnd = nullptr;
      40              :     {
      41           56 :         SerializedQNameIterator it(validData, *start);
      42           56 :         nameEnd = it.FindDataEnd();
      43              :     }
      44           56 :     if (nameEnd == nullptr)
      45              :     {
      46            0 :         return false;
      47              :     }
      48              : 
      49           56 :     if (!validData.Contains(nameEnd + 3))
      50              :     {
      51            0 :         return false;
      52              :     }
      53              : 
      54              :     // TODO: should there be checks for valid mType/class?
      55              : 
      56           56 :     mType = static_cast<QType>(chip::Encoding::BigEndian::Read16(nameEnd));
      57              : 
      58           56 :     uint16_t klass = chip::Encoding::BigEndian::Read16(nameEnd);
      59              : 
      60           56 :     mAnswerViaUnicast = (klass & kQClassUnicastAnswerFlag) != 0;
      61           56 :     mClass            = static_cast<QClass>(klass & ~kQClassUnicastAnswerFlag);
      62           56 :     mNameIterator     = SerializedQNameIterator(validData, *start);
      63              : 
      64           56 :     *start = nameEnd;
      65              : 
      66           56 :     return true;
      67              : }
      68              : 
      69           32 : bool QueryData::Append(HeaderRef & hdr, RecordWriter & out) const
      70              : {
      71           32 :     if ((hdr.GetAdditionalCount() != 0) || (hdr.GetAnswerCount() != 0) || (hdr.GetAuthorityCount() != 0))
      72              :     {
      73            0 :         return false;
      74              :     }
      75              : 
      76           32 :     out.WriteQName(GetName())
      77           32 :         .Put16(static_cast<uint16_t>(mType))
      78           32 :         .Put16(static_cast<uint16_t>(static_cast<uint16_t>(mClass) | (mAnswerViaUnicast ? kQClassUnicastAnswerFlag : 0)));
      79              : 
      80           32 :     if (!out.Fit())
      81              :     {
      82            0 :         return false;
      83              :     }
      84              : 
      85           32 :     hdr.SetQueryCount(static_cast<uint16_t>(hdr.GetQueryCount() + 1));
      86           32 :     return true;
      87              : }
      88              : 
      89          328 : bool ResourceData::Parse(const BytesRange & validData, const uint8_t ** start)
      90              : {
      91              :     // Structure is:
      92              :     //    QNAME
      93              :     //    TYPE      (16 bit)
      94              :     //    CLASS     (16 bit)
      95              :     //    TTL       (32 bit)
      96              :     //    RDLENGTH  (16 bit)
      97              :     //    <DATA>    (RDLENGTH bytes)
      98          328 :     if (!validData.Contains(*start))
      99              :     {
     100            0 :         return false;
     101              :     }
     102              : 
     103          328 :     const uint8_t * nameEnd = nullptr;
     104              : 
     105              :     {
     106          328 :         SerializedQNameIterator it(validData, *start);
     107          328 :         nameEnd = it.FindDataEnd();
     108              :     }
     109          328 :     if (nameEnd == nullptr)
     110              :     {
     111            0 :         return false;
     112              :     }
     113              : 
     114              :     // need 3*u16 + u32
     115          328 :     if (!validData.Contains(nameEnd + 9))
     116              :     {
     117            0 :         return false;
     118              :     }
     119              : 
     120          328 :     mType  = static_cast<QType>(chip::Encoding::BigEndian::Read16(nameEnd));
     121          328 :     mClass = static_cast<QClass>(chip::Encoding::BigEndian::Read16(nameEnd));
     122          328 :     mTtl   = chip::Encoding::BigEndian::Read32(nameEnd);
     123              : 
     124          328 :     uint16_t dataLen = chip::Encoding::BigEndian::Read16(nameEnd); // resource data
     125              : 
     126          328 :     if (!validData.Contains(nameEnd + dataLen - 1))
     127              :     {
     128            0 :         return false; // no space for RDATA
     129              :     }
     130          328 :     mData = BytesRange(nameEnd, nameEnd + dataLen);
     131              : 
     132          328 :     mNameIterator = SerializedQNameIterator(validData, *start);
     133              : 
     134          328 :     *start = nameEnd + dataLen;
     135              : 
     136          328 :     return true;
     137              : }
     138              : 
     139           80 : bool ParsePacket(const BytesRange & packetData, ParserDelegate * delegate)
     140              : {
     141           80 :     if (packetData.Size() < static_cast<ptrdiff_t>(HeaderRef::kSizeBytes))
     142              :     {
     143            0 :         return false;
     144              :     }
     145              : 
     146              :     // header is used as const, so cast is safe
     147           80 :     ConstHeaderRef header(packetData.Start());
     148              : 
     149           80 :     if (!header.GetFlags().IsValidMdns())
     150              :     {
     151            0 :         return false;
     152              :     }
     153              : 
     154           80 :     delegate->OnHeader(header);
     155              : 
     156           80 :     const uint8_t * data = packetData.Start() + HeaderRef::kSizeBytes;
     157              : 
     158              :     {
     159           80 :         QueryData queryData;
     160          136 :         for (uint16_t i = 0; i < header.GetQueryCount(); i++)
     161              :         {
     162           56 :             if (!queryData.Parse(packetData, &data))
     163              :             {
     164            0 :                 return false;
     165              :             }
     166              : 
     167           56 :             delegate->OnQuery(queryData);
     168              :         }
     169              :     }
     170              : 
     171              :     {
     172           80 :         ResourceData resourceData;
     173          369 :         for (uint16_t i = 0; i < header.GetAnswerCount(); i++)
     174              :         {
     175          289 :             if (!resourceData.Parse(packetData, &data))
     176              :             {
     177            0 :                 return false;
     178              :             }
     179              : 
     180          289 :             delegate->OnResource(ResourceType::kAnswer, resourceData);
     181              :         }
     182              : 
     183           80 :         for (uint16_t i = 0; i < header.GetAuthorityCount(); i++)
     184              :         {
     185            0 :             if (!resourceData.Parse(packetData, &data))
     186              :             {
     187            0 :                 return false;
     188              :             }
     189              : 
     190            0 :             delegate->OnResource(ResourceType::kAuthority, resourceData);
     191              :         }
     192              : 
     193          102 :         for (uint16_t i = 0; i < header.GetAdditionalCount(); i++)
     194              :         {
     195           22 :             if (!resourceData.Parse(packetData, &data))
     196              :             {
     197            0 :                 return false;
     198              :             }
     199              : 
     200           22 :             delegate->OnResource(ResourceType::kAdditional, resourceData);
     201              :         }
     202              :     }
     203              : 
     204           80 :     return true;
     205              : }
     206              : 
     207              : } // namespace Minimal
     208              : } // namespace mdns
        

Generated by: LCOV version 2.0-1