aaaa_28.cc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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 <exceptions/exceptions.h>
  15. #include <util/buffer.h>
  16. #include <dns/exceptions.h>
  17. #include <dns/messagerenderer.h>
  18. #include <dns/rdata.h>
  19. #include <dns/rdataclass.h>
  20. #include <dns/master_lexer.h>
  21. #include <dns/master_loader.h>
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <string>
  25. #include <arpa/inet.h> // XXX: for inet_pton/ntop(), not exist in C++ standards
  26. #include <sys/socket.h> // for AF_INET/AF_INET6
  27. using namespace std;
  28. using namespace isc::util;
  29. // BEGIN_ISC_NAMESPACE
  30. // BEGIN_RDATA_NAMESPACE
  31. AAAA::AAAA(const std::string& addrstr) {
  32. if (inet_pton(AF_INET6, addrstr.c_str(), &addr_) != 1) {
  33. isc_throw(InvalidRdataText,
  34. "IN/AAAA RDATA construction from text failed: "
  35. "Address cannot be converted: " << addrstr);
  36. }
  37. }
  38. AAAA::AAAA(MasterLexer& lexer, const Name*,
  39. MasterLoader::Options, MasterLoaderCallbacks&)
  40. {
  41. const MasterToken& token = lexer.getNextToken(MasterToken::STRING);
  42. if (inet_pton(AF_INET6, token.getStringRegion().beg, &addr_) != 1) {
  43. isc_throw(InvalidRdataText, "Failed to convert '"
  44. << token.getString() << "' to IN/AAAA RDATA");
  45. }
  46. }
  47. AAAA::AAAA(InputBuffer& buffer, size_t rdata_len) {
  48. if (rdata_len != sizeof(addr_)) {
  49. isc_throw(DNSMessageFORMERR,
  50. "IN/AAAA RDATA construction from wire failed: "
  51. "Invalid length: " << rdata_len);
  52. }
  53. if (buffer.getLength() - buffer.getPosition() < sizeof(addr_)) {
  54. isc_throw(DNSMessageFORMERR,
  55. "IN/AAAA RDATA construction from wire failed: "
  56. "insufficient buffer length: "
  57. << buffer.getLength() - buffer.getPosition());
  58. }
  59. buffer.readData(&addr_, sizeof(addr_));
  60. }
  61. AAAA::AAAA(const AAAA& other) : Rdata() {
  62. memcpy(addr_, other.addr_, sizeof(addr_));
  63. }
  64. void
  65. AAAA::toWire(OutputBuffer& buffer) const {
  66. buffer.writeData(&addr_, sizeof(addr_));
  67. }
  68. void
  69. AAAA::toWire(AbstractMessageRenderer& renderer) const {
  70. renderer.writeData(&addr_, sizeof(addr_));
  71. }
  72. string
  73. AAAA::toText() const {
  74. char addr_string[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
  75. if (inet_ntop(AF_INET6, &addr_, addr_string, sizeof(addr_string)) == NULL) {
  76. isc_throw(Unexpected,
  77. "Failed to convert IN/AAAA RDATA to textual IPv6 address");
  78. }
  79. return (string(addr_string));
  80. }
  81. int
  82. AAAA::compare(const Rdata& other) const {
  83. const AAAA& other_a = dynamic_cast<const AAAA&>(other);
  84. return (memcmp(&addr_, &other_a.addr_, sizeof(addr_)));
  85. }
  86. // END_RDATA_NAMESPACE
  87. // END_ISC_NAMESPACE