ns_rr_cursor_next.c 2.2 KB

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