1
0

ns_parse.c 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. /*
  2. * Copyright (c) 1996,1999 by Internet Software Consortium.
  3. *
  4. * Permission to use, copy, modify, and distribute this software for any
  5. * purpose with or without fee is hereby granted, provided that the above
  6. * copyright notice and this permission notice appear in all copies.
  7. *
  8. * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  9. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  10. * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  11. * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  12. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  13. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  14. * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  15. * SOFTWARE.
  16. */
  17. /*
  18. * Modified by Hotbird64 for use with vlmcs.
  19. */
  20. #ifndef CONFIG
  21. #define CONFIG "config.h"
  22. #endif // CONFIG
  23. #include CONFIG
  24. #ifdef DNS_PARSER_INTERNAL
  25. #ifndef NO_DNS
  26. /* Import. */
  27. #include <sys/types.h>
  28. #include <errno.h>
  29. #include <string.h>
  30. #include "types.h"
  31. #include "endian.h"
  32. #include "ns_name.h"
  33. #include "ns_parse.h"
  34. /* Macros. */
  35. #define NS_GET16_VLMCSD(s, cp) do { \
  36. (s) = GET_UA16BE(cp); \
  37. (cp) += NS_INT16SZ; \
  38. } while (0)
  39. #define NS_GET32_VLMCSD(l, cp) do { \
  40. (l) = GET_UA32BE(cp); \
  41. (cp) += NS_INT32SZ; \
  42. } while (0)
  43. #define RETERR(err) do { errno = (err); return (-1); } while (0)
  44. /* Forward. */
  45. static void setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect);
  46. static int dn_skipname_vlmcsd(const unsigned char *s, const unsigned char *end)
  47. {
  48. const unsigned char *p;
  49. for (p=s; p<end; p++)
  50. if (!*p) return p-s+1;
  51. else if (*p>=192)
  52. {if (p+1<end) return p-s+2;
  53. else break;}
  54. return -1;
  55. }
  56. static int
  57. ns_skiprr_vlmcsd(const uint8_t *ptr, const uint8_t *eom, ns_sect_vlmcsd section, int count) {
  58. const uint8_t *optr = ptr;
  59. for ((void)NULL; count > 0; count--) {
  60. int b, rdlength;
  61. b = dn_skipname_vlmcsd(ptr, eom);
  62. if (b < 0)
  63. RETERR(EMSGSIZE);
  64. ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
  65. if (section != ns_s_qd_vlmcsd) {
  66. if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
  67. RETERR(EMSGSIZE);
  68. ptr += NS_INT32SZ/*TTL*/;
  69. NS_GET16_VLMCSD(rdlength, ptr);
  70. ptr += rdlength/*RData*/;
  71. }
  72. }
  73. if (ptr > eom)
  74. RETERR(EMSGSIZE);
  75. return (ptr - optr);
  76. }
  77. int
  78. ns_initparse_vlmcsd(const uint8_t *msg, int msglen, ns_msg_vlmcsd *handle) {
  79. const uint8_t *eom = msg + msglen;
  80. int i;
  81. memset(handle, 0x5e, sizeof *handle);
  82. handle->_msg = msg;
  83. handle->_eom = eom;
  84. if (msg + NS_INT16SZ > eom)
  85. RETERR(EMSGSIZE);
  86. NS_GET16_VLMCSD(handle->_id, msg);
  87. if (msg + NS_INT16SZ > eom)
  88. RETERR(EMSGSIZE);
  89. NS_GET16_VLMCSD(handle->_flags, msg);
  90. for (i = 0; i < ns_s_max_vlmcsd; i++) {
  91. if (msg + NS_INT16SZ > eom)
  92. RETERR(EMSGSIZE);
  93. NS_GET16_VLMCSD(handle->_counts[i], msg);
  94. }
  95. for (i = 0; i < ns_s_max_vlmcsd; i++)
  96. if (handle->_counts[i] == 0)
  97. handle->_sections[i] = NULL;
  98. else {
  99. int b = ns_skiprr_vlmcsd(msg, eom, (ns_sect_vlmcsd)i,
  100. handle->_counts[i]);
  101. if (b < 0)
  102. return (-1);
  103. handle->_sections[i] = msg;
  104. msg += b;
  105. }
  106. if (msg > eom)
  107. RETERR(EMSGSIZE);
  108. handle->_eom = msg;
  109. setsection_vlmcsd(handle, ns_s_max_vlmcsd);
  110. return (0);
  111. }
  112. int
  113. ns_parserr_vlmcsd(ns_msg_vlmcsd *handle, ns_sect_vlmcsd section, int rrnum, ns_rr_vlmcsd *rr) {
  114. int b;
  115. /* Make section right. */
  116. if (section >= ns_s_max_vlmcsd)
  117. RETERR(ENODEV);
  118. if (section != handle->_sect)
  119. setsection_vlmcsd(handle, section);
  120. /* Make rrnum right. */
  121. if (rrnum == -1)
  122. rrnum = handle->_rrnum;
  123. if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
  124. RETERR(ENODEV);
  125. if (rrnum < handle->_rrnum)
  126. setsection_vlmcsd(handle, section);
  127. if (rrnum > handle->_rrnum) {
  128. b = ns_skiprr_vlmcsd(handle->_msg_ptr, handle->_eom, section,
  129. rrnum - handle->_rrnum);
  130. if (b < 0)
  131. return (-1);
  132. handle->_msg_ptr += b;
  133. handle->_rrnum = rrnum;
  134. }
  135. /* Do the parse. */
  136. b = ns_name_uncompress_vlmcsd(handle->_msg, handle->_eom,
  137. handle->_msg_ptr, rr->name, NS_MAXDNAME);
  138. if (b < 0)
  139. return (-1);
  140. handle->_msg_ptr += b;
  141. if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
  142. RETERR(EMSGSIZE);
  143. NS_GET16_VLMCSD(rr->type, handle->_msg_ptr);
  144. NS_GET16_VLMCSD(rr->rr_class, handle->_msg_ptr);
  145. if (section == ns_s_qd_vlmcsd) {
  146. rr->ttl = 0;
  147. rr->rdlength = 0;
  148. rr->rdata = NULL;
  149. } else {
  150. if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
  151. RETERR(EMSGSIZE);
  152. NS_GET32_VLMCSD(rr->ttl, handle->_msg_ptr);
  153. NS_GET16_VLMCSD(rr->rdlength, handle->_msg_ptr);
  154. if (handle->_msg_ptr + rr->rdlength > handle->_eom)
  155. RETERR(EMSGSIZE);
  156. rr->rdata = handle->_msg_ptr;
  157. handle->_msg_ptr += rr->rdlength;
  158. }
  159. if (++handle->_rrnum > handle->_counts[(int)section])
  160. setsection_vlmcsd(handle, (ns_sect_vlmcsd)((int)section + 1));
  161. /* All done. */
  162. return (0);
  163. }
  164. /* Private. */
  165. static void
  166. setsection_vlmcsd(ns_msg_vlmcsd *msg, ns_sect_vlmcsd sect) {
  167. msg->_sect = sect;
  168. if (sect == ns_s_max_vlmcsd) {
  169. msg->_rrnum = -1;
  170. msg->_msg_ptr = NULL;
  171. } else {
  172. msg->_rrnum = 0;
  173. msg->_msg_ptr = msg->_sections[(int)sect];
  174. }
  175. }
  176. #endif // !NO_DNS
  177. #endif // DNS_PARSER_INTERNAL