rrset.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. // Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // Permission to use, copy, modify, and/or distribute this software for any
  4. // purpose with or without fee is hereby granted, provided that the above
  5. // copyright notice and this permission notice appear in all copies.
  6. //
  7. // THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  8. // REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  9. // AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  10. // INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  11. // LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  12. // OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  13. // PERFORMANCE OF THIS SOFTWARE.
  14. // $Id$
  15. #include <sys/types.h>
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <arpa/inet.h>
  19. #include <stdexcept>
  20. #include <cstring>
  21. #include <dns/buffer.h>
  22. #include <dns/rrset.h>
  23. using ISC::DNS::RRClass;
  24. using ISC::DNS::RRType;
  25. using ISC::DNS::TTL;
  26. using ISC::DNS::Rdata::IN::A;
  27. using ISC::DNS::Rdata::IN::AAAA;
  28. using ISC::DNS::Rdata::Generic::NS;
  29. RRClass::RRClass(const std::string& classstr)
  30. {
  31. // XXX: this is a quick hack implementation to see feasibility.
  32. // should be rewritten in a cleaner way.
  33. if (classstr == "IN")
  34. classval_ = 1;
  35. else if (classstr == "CHAOS" || classstr == "CH")
  36. classval_ = 3;
  37. else
  38. throw DNSInvalidRRClass();
  39. }
  40. const std::string
  41. RRClass::to_text() const
  42. {
  43. // XXX: quick hack
  44. if (classval_ == 1)
  45. return ("IN");
  46. else if (classval_ == 3)
  47. return ("CH");
  48. throw std::runtime_error("unexpected class");
  49. }
  50. void
  51. RRClass::to_wire(ISC::Buffer& b) const
  52. {
  53. b.write_uint16(classval_);
  54. }
  55. const RRClass RRClass::IN("IN");
  56. const RRClass RRClass::CH("CH");
  57. RRType::RRType(const std::string& typestr)
  58. {
  59. // XXX: this is a quick hack implementation to see feasibility.
  60. // should be rewritten in a cleaner way.
  61. if (typestr == "A")
  62. typeval_ = 1;
  63. else if (typestr == "NS")
  64. typeval_ = 2;
  65. else if (typestr == "AAAA")
  66. typeval_ = 28;
  67. else
  68. throw DNSInvalidRRType();
  69. }
  70. const std::string
  71. RRType::to_text() const
  72. {
  73. if (typeval_ == 1)
  74. return ("A");
  75. else if (typeval_ == 2)
  76. return ("NS");
  77. else if (typeval_ == 28)
  78. return ("AAAA");
  79. throw std::runtime_error("unexpected type");
  80. }
  81. void
  82. RRType::to_wire(Buffer& buffer) const
  83. {
  84. buffer.write_uint16(typeval_);
  85. }
  86. const RRType RRType::A("A");
  87. const RRType RRType::NS("NS");
  88. const RRType RRType::AAAA("AAAA");
  89. // ...more to follow
  90. void
  91. TTL::to_wire(Buffer& buffer) const
  92. {
  93. buffer.write_uint32(ttlval_);
  94. }
  95. A::A(const std::string& addrstr)
  96. {
  97. if (inet_pton(AF_INET, addrstr.c_str(), &addr_) != 1)
  98. throw ISCInvalidAddressString();
  99. }
  100. void
  101. A::from_wire(Buffer& buffer, NameDecompressor& decompressor)
  102. {
  103. //TBD
  104. }
  105. void
  106. A::to_wire(Buffer& buffer, NameCompressor& compressor) const
  107. {
  108. buffer.write_uint16(sizeof(addr_));
  109. buffer.write_data(&addr_, sizeof(addr_));
  110. }
  111. std::string
  112. A::to_text() const
  113. {
  114. char addrbuf[sizeof("255.255.255.255")];
  115. if (inet_ntop(AF_INET, &addr_, addrbuf, sizeof(addrbuf)) == NULL)
  116. throw std::runtime_error("unexpected inet_ntop() failure");
  117. return (std::string(addrbuf));
  118. }
  119. AAAA::AAAA(const std::string& addrstr)
  120. {
  121. if (inet_pton(AF_INET6, addrstr.c_str(), &addr_) != 1)
  122. throw ISCInvalidAddressString();
  123. }
  124. void
  125. AAAA::from_wire(Buffer& buffer, NameDecompressor& decompressor)
  126. {
  127. //TBD
  128. }
  129. void
  130. AAAA::to_wire(Buffer& buffer, NameCompressor& compressor) const
  131. {
  132. buffer.write_uint16(sizeof(addr_));
  133. buffer.write_data(&addr_, sizeof(addr_));
  134. }
  135. std::string
  136. AAAA::to_text() const
  137. {
  138. char addrbuf[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
  139. if (inet_ntop(AF_INET6, &addr_, addrbuf, sizeof(addrbuf)) == NULL)
  140. throw std::runtime_error("unexpected inet_ntop() failure");
  141. return (std::string(addrbuf));
  142. }
  143. void
  144. NS::from_wire(Buffer& buffer, NameDecompressor& decompressor)
  145. {
  146. //TBD
  147. }
  148. void
  149. NS::to_wire(Buffer& buffer, NameCompressor& compressor) const
  150. {
  151. // XXX: note that a complete implementation cannot be this simple
  152. // because we need to disable compression for the NS name.
  153. buffer.write_uint16(nsname_.get_length());
  154. nsname_.to_wire(buffer, compressor);
  155. }
  156. std::string
  157. NS::to_text() const
  158. {
  159. return (nsname_.to_text());
  160. }
  161. #ifdef notyet
  162. void
  163. RdataSet::add_rdata(rdataptr_t rdata)
  164. {
  165. if (rdata->get_type() != _rdtype)
  166. throw DNSRdtypeMismatch();
  167. _rdatalist.push_back(rdata);
  168. }
  169. std::string
  170. RdataSet::to_text() const
  171. {
  172. std::string s;
  173. for (vector<rdataptr_t>::const_iterator it = _rdatalist.begin();
  174. it != _rdatalist.end();
  175. ++it)
  176. {
  177. if (!s.empty())
  178. s.push_back('\n');
  179. s += _ttl.to_text() + " " + _rdclass.to_text() + " " +
  180. _rdtype.to_text() + " " + (**it).to_text();
  181. }
  182. return (s);
  183. }
  184. std::string
  185. RRSet::to_text() const
  186. {
  187. std::string s;
  188. for (vector<rdataptr_t>::const_iterator it = _rdatalist.begin();
  189. it != _rdatalist.end();
  190. ++it)
  191. {
  192. if (!s.empty())
  193. s.push_back('\n');
  194. s += _name.to_text() + " ";
  195. s += _ttl.to_text() + " " + _rdclass.to_text() + " " +
  196. _rdtype.to_text() + " " + (**it).to_text();
  197. }
  198. return (s);
  199. }
  200. void
  201. RRSet::add_rdata(rdataptr_t rdata)
  202. {
  203. if (rdata->get_type() != _rdtype)
  204. throw DNSRdtypeMismatch();
  205. _rdatalist.push_back(rdata);
  206. }
  207. int
  208. RRSet::to_wire(Message& message, section_t section)
  209. {
  210. int num_rrs = 0;
  211. // sort Rdata list based on rrset-order and sortlist, and possible
  212. // other options. Details to be considered.
  213. Buffer& b = message.get_iobuffer();
  214. NameCompressor& c = message.get_compressor();
  215. for (vector<rdataptr_t>::iterator it = _rdatalist.begin();
  216. it != _rdatalist.end();
  217. ++it, ++num_rrs)
  218. {
  219. _name.to_wire(b, c);
  220. _rdtype.to_wire(b);
  221. _rdclass.to_wire(b);
  222. _ttl.to_wire(b);
  223. (**it).to_wire(b, c);
  224. // TBD: handle truncation case
  225. }
  226. return (num_rrs);
  227. }
  228. std::string
  229. Question::to_text() const
  230. {
  231. // return in dig-style format. note that in the wire format class follows
  232. // type.
  233. return (_name.to_text() + " " + _rdclass.to_text() + " " +
  234. _rdtype.to_text());
  235. }
  236. int
  237. Question::to_wire(Message& message, section_t section)
  238. {
  239. Buffer& b = message.get_iobuffer();
  240. NameCompressor& c = message.get_compressor();
  241. _name.to_wire(b, c);
  242. _rdtype.to_wire(b);
  243. _rdclass.to_wire(b);
  244. return (1);
  245. }
  246. #endif // notyet