dhcid_49.cc 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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. #include <stdint.h>
  15. #include <string.h>
  16. #include <string>
  17. #include <exceptions/exceptions.h>
  18. #include <util/buffer.h>
  19. #include <util/encode/hex.h>
  20. #include <dns/exceptions.h>
  21. #include <dns/messagerenderer.h>
  22. #include <dns/rdata.h>
  23. #include <dns/rdataclass.h>
  24. using namespace std;
  25. using namespace isc::util;
  26. // BEGIN_ISC_NAMESPACE
  27. // BEGIN_RDATA_NAMESPACE
  28. /// \brief Constructor from string.
  29. ///
  30. /// \param dhcid_str A base-64 representation of the DHCID binary data.
  31. /// The data is considered to be opaque, but a sanity check is performed.
  32. ///
  33. /// <b>Exceptions</b>
  34. ///
  35. /// \c dhcid_str must be a valid BASE-64 string, otherwise an exception
  36. /// of class \c isc::BadValue will be thrown;
  37. /// the binary data should consist of at leat of 3 octets as per RFC4701:
  38. /// < 2 octets > Identifier type code
  39. /// < 1 octet > Digest type code
  40. /// < n octets > Digest (length depends on digest type)
  41. /// If the data is less than 3 octets (i.e. it cannot contain id type code and
  42. /// digest type code), an exception of class \c InvalidRdataLength is thrown.
  43. DHCID::DHCID(const string& dhcid_str) {
  44. istringstream iss(dhcid_str);
  45. stringbuf digestbuf;
  46. iss >> &digestbuf;
  47. isc::util::encode::decodeHex(digestbuf.str(), digest_);
  48. // RFC4701 states DNS software should consider the RDATA section to
  49. // be opaque, but there must be at least three bytes in the data:
  50. // < 2 octets > Identifier type code
  51. // < 1 octet > Digest type code
  52. if (digest_.size() < 3) {
  53. isc_throw(InvalidRdataLength, "DHCID length " << digest_.size() <<
  54. " too short, need at least 3 bytes");
  55. }
  56. }
  57. /// \brief Constructor from wire-format data.
  58. ///
  59. /// \param buffer A buffer storing the wire format data.
  60. /// \param rdata_len The length of the RDATA in bytes
  61. ///
  62. /// <b>Exceptions</b>
  63. /// \c InvalidRdataLength is thrown if \c rdata_len is than minimum of 3 octets
  64. DHCID::DHCID(InputBuffer& buffer, size_t rdata_len) {
  65. if (rdata_len < 3) {
  66. isc_throw(InvalidRdataLength, "DHCID length " << rdata_len <<
  67. " too short, need at least 3 bytes");
  68. }
  69. digest_.resize(rdata_len);
  70. buffer.readData(&digest_[0], rdata_len);
  71. }
  72. /// \brief The copy constructor.
  73. ///
  74. /// This trivial copy constructor never throws an exception.
  75. DHCID::DHCID(const DHCID& other) : Rdata(), digest_(other.digest_)
  76. {}
  77. /// \brief Render the \c DHCID in the wire format.
  78. ///
  79. /// \param buffer An output buffer to store the wire data.
  80. void
  81. DHCID::toWire(OutputBuffer& buffer) const {
  82. buffer.writeData(&digest_[0], digest_.size());
  83. }
  84. /// \brief Render the \c DHCID in the wire format into a
  85. /// \c MessageRenderer object.
  86. ///
  87. /// \param renderer DNS message rendering context that encapsulates the
  88. /// output buffer in which the \c DHCID is to be stored.
  89. void
  90. DHCID::toWire(AbstractMessageRenderer& renderer) const {
  91. renderer.writeData(&digest_[0], digest_.size());
  92. }
  93. /// \brief Convert the \c DHCID to a string.
  94. ///
  95. /// This method returns a \c std::string object representing the \c DHCID.
  96. ///
  97. /// \return A string representation of \c DHCID.
  98. string
  99. DHCID::toText() const {
  100. return (isc::util::encode::encodeHex(digest_));
  101. }
  102. /// \brief Compare two instances of \c DHCID RDATA.
  103. ///
  104. /// See documentation in \c Rdata.
  105. int
  106. DHCID::compare(const Rdata& other) const {
  107. const DHCID& other_dhcid = dynamic_cast<const DHCID&>(other);
  108. size_t this_len = digest_.size();
  109. size_t other_len = other_dhcid.digest_.size();
  110. size_t cmplen = min(this_len, other_len);
  111. int cmp = memcmp(&digest_[0], &other_dhcid.digest_[0], cmplen);
  112. if (cmp != 0) {
  113. return (cmp);
  114. } else {
  115. return ((this_len == other_len) ? 0 : (this_len < other_len) ? -1 : 1);
  116. }
  117. }
  118. /// \brief Accessor method to get the DHCID digest
  119. ///
  120. /// \return A reference to the binary DHCID data
  121. const std::vector<uint8_t>&
  122. DHCID::getDigest() const {
  123. return (digest_);
  124. }
  125. // END_RDATA_NAMESPACE
  126. // END_ISC_NAMESPACE