(root)/
glibc-2.38/
resolv/
ns_rr_cursor_next.c
       1  /* Simple DNS record parser without textual name decoding.
       2     Copyright (C) 2022-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <arpa/nameser.h>
      20  #include <errno.h>
      21  #include <stdbool.h>
      22  #include <string.h>
      23  
      24  bool
      25  __ns_rr_cursor_next (struct ns_rr_cursor *c, struct ns_rr_wire *rr)
      26  {
      27    rr->rdata = NULL;
      28  
      29    /* Extract the record owner name.  */
      30    int consumed = __ns_name_unpack (c->begin, c->end, c->current,
      31                                     rr->rname, sizeof (rr->rname));
      32    if (consumed < 0)
      33      {
      34        memset (rr, 0, sizeof (*rr));
      35        __set_errno (EMSGSIZE);
      36        return false;
      37      }
      38    c->current += consumed;
      39  
      40    /* Extract the metadata.  */
      41    struct
      42    {
      43      uint16_t rtype;
      44      uint16_t rclass;
      45      uint32_t ttl;
      46      uint16_t rdlength;
      47    } __attribute__ ((packed)) metadata;
      48    _Static_assert (sizeof (metadata) == 10, "sizeof metadata");
      49    if (c->end - c->current < sizeof (metadata))
      50      {
      51        memset (rr, 0, sizeof (*rr));
      52        __set_errno (EMSGSIZE);
      53        return false;
      54      }
      55    memcpy (&metadata, c->current, sizeof (metadata));
      56    c->current += sizeof (metadata);
      57    /* Endianness conversion.  */
      58    rr->rtype = ntohs (metadata.rtype);
      59    rr->rclass = ntohs (metadata.rclass);
      60    rr->ttl = ntohl (metadata.ttl);
      61    rr->rdlength = ntohs (metadata.rdlength);
      62  
      63    /* Extract record data.  */
      64    if (c->end - c->current < rr->rdlength)
      65      {
      66        memset (rr, 0, sizeof (*rr));
      67        __set_errno (EMSGSIZE);
      68        return false;
      69      }
      70    rr->rdata = c->current;
      71    c->current += rr->rdlength;
      72  
      73    return true;
      74  }