ds_43.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. // Copyright (C) 2010 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 <iostream>
  16. #include <string>
  17. #include <sstream>
  18. #include <vector>
  19. #include <boost/lexical_cast.hpp>
  20. #include <dns/buffer.h>
  21. #include <dns/hex.h>
  22. #include <dns/messagerenderer.h>
  23. #include <dns/name.h>
  24. #include <dns/rdata.h>
  25. #include <dns/rdataclass.h>
  26. #include <stdio.h>
  27. #include <time.h>
  28. using namespace std;
  29. // BEGIN_ISC_NAMESPACE
  30. // BEGIN_RDATA_NAMESPACE
  31. struct DSImpl {
  32. // straightforward representation of DS RDATA fields
  33. DSImpl(uint16_t tag, uint8_t algorithm, uint8_t digest_type,
  34. const vector<uint8_t>& digest) :
  35. tag_(tag), algorithm_(algorithm), digest_type_(digest_type),
  36. digest_(digest)
  37. {}
  38. uint16_t tag_;
  39. uint8_t algorithm_;
  40. uint8_t digest_type_;
  41. const vector<uint8_t> digest_;
  42. };
  43. DS::DS(const string& ds_str) :
  44. impl_(NULL)
  45. {
  46. istringstream iss(ds_str);
  47. unsigned int tag, algorithm, digest_type;
  48. stringbuf digestbuf;
  49. iss >> tag >> algorithm >> digest_type >> &digestbuf;
  50. if (iss.bad() || iss.fail()) {
  51. isc_throw(InvalidRdataText, "Invalid DS text");
  52. }
  53. if (tag > 0xffff) {
  54. isc_throw(InvalidRdataText, "DS tag out of range");
  55. }
  56. if (algorithm > 0xff) {
  57. isc_throw(InvalidRdataText, "DS algorithm out of range");
  58. }
  59. if (digest_type > 0xff) {
  60. isc_throw(InvalidRdataText, "DS digest type out of range");
  61. }
  62. vector<uint8_t> digest;
  63. decodeHex(digestbuf.str(), digest);
  64. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  65. }
  66. DS::DS(InputBuffer& buffer, size_t rdata_len)
  67. {
  68. if (rdata_len < 4) {
  69. isc_throw(InvalidRdataLength, "DS too short");
  70. }
  71. uint16_t tag = buffer.readUint16();
  72. uint16_t algorithm = buffer.readUint8();
  73. uint16_t digest_type = buffer.readUint8();
  74. rdata_len -= 4;
  75. vector<uint8_t> digest(rdata_len);
  76. buffer.readData(&digest[0], rdata_len);
  77. impl_ = new DSImpl(tag, algorithm, digest_type, digest);
  78. }
  79. DS::DS(const DS& source) :
  80. Rdata(), impl_(new DSImpl(*source.impl_))
  81. {}
  82. DS&
  83. DS::operator=(const DS& source)
  84. {
  85. if (impl_ == source.impl_) {
  86. return (*this);
  87. }
  88. DSImpl* newimpl = new DSImpl(*source.impl_);
  89. delete impl_;
  90. impl_ = newimpl;
  91. return (*this);
  92. }
  93. DS::~DS()
  94. {
  95. delete impl_;
  96. }
  97. string
  98. DS::toText() const
  99. {
  100. using namespace boost;
  101. return (lexical_cast<string>(static_cast<int>(impl_->tag_)) +
  102. " " + lexical_cast<string>(static_cast<int>(impl_->algorithm_)) +
  103. " " + lexical_cast<string>(static_cast<int>(impl_->digest_type_)) +
  104. " " + encodeHex(impl_->digest_));
  105. }
  106. void
  107. DS::toWire(OutputBuffer& buffer) const
  108. {
  109. buffer.writeUint16(impl_->tag_);
  110. buffer.writeUint8(impl_->algorithm_);
  111. buffer.writeUint8(impl_->digest_type_);
  112. buffer.writeData(&impl_->digest_[0], impl_->digest_.size());
  113. }
  114. void
  115. DS::toWire(MessageRenderer& renderer) const
  116. {
  117. renderer.writeUint16(impl_->tag_);
  118. renderer.writeUint8(impl_->algorithm_);
  119. renderer.writeUint8(impl_->digest_type_);
  120. renderer.writeData(&impl_->digest_[0], impl_->digest_.size());
  121. }
  122. int
  123. DS::compare(const Rdata& other) const
  124. {
  125. const DS& other_ds = dynamic_cast<const DS&>(other);
  126. if (impl_->tag_ != other_ds.impl_->tag_) {
  127. return (impl_->tag_ < other_ds.impl_->tag_ ? -1 : 1);
  128. }
  129. if (impl_->algorithm_ != other_ds.impl_->algorithm_) {
  130. return (impl_->algorithm_ < other_ds.impl_->algorithm_ ? -1 : 1);
  131. }
  132. if (impl_->digest_type_ != other_ds.impl_->digest_type_) {
  133. return (impl_->digest_type_ < other_ds.impl_->digest_type_ ? -1 : 1);
  134. }
  135. size_t this_len = impl_->digest_.size();
  136. size_t other_len = other_ds.impl_->digest_.size();
  137. size_t cmplen = min(this_len, other_len);
  138. int cmp = memcmp(&impl_->digest_[0], &other_ds.impl_->digest_[0], cmplen);
  139. if (cmp != 0) {
  140. return (cmp);
  141. } else {
  142. return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
  143. }
  144. }
  145. uint16_t
  146. DS::getTag() const {
  147. return impl_->tag_;
  148. }
  149. // END_RDATA_NAMESPACE
  150. // END_ISC_NAMESPACE