option6_ia.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. // Copyright (C) 2011-2012 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 <dhcp/dhcp6.h>
  15. #include <dhcp/libdhcp++.h>
  16. #include <dhcp/option6_ia.h>
  17. #include <exceptions/exceptions.h>
  18. #include <util/io_utilities.h>
  19. #include <arpa/inet.h>
  20. #include <sstream>
  21. #include <stdint.h>
  22. using namespace std;
  23. using namespace isc::util;
  24. namespace isc {
  25. namespace dhcp {
  26. Option6IA::Option6IA(uint16_t type, uint32_t iaid)
  27. :Option(Option::V6, type), iaid_(iaid), t1_(0), t2_(0) {
  28. // IA_TA has different layout than IA_NA and IA_PD. We can't sue this class
  29. if (type == D6O_IA_TA) {
  30. isc_throw(BadValue, "Can't use Option6IA for IA_TA as it has "
  31. "a different layout");
  32. }
  33. }
  34. Option6IA::Option6IA(uint16_t type, OptionBufferConstIter begin,
  35. OptionBufferConstIter end)
  36. :Option(Option::V6, type) {
  37. // IA_TA has different layout than IA_NA and IA_PD. We can't use this class
  38. if (type == D6O_IA_TA) {
  39. isc_throw(BadValue, "Can't use Option6IA for IA_TA as it has "
  40. "a different layout");
  41. }
  42. unpack(begin, end);
  43. }
  44. void Option6IA::pack(isc::util::OutputBuffer& buf) {
  45. buf.writeUint16(type_);
  46. buf.writeUint16(len() - OPTION6_HDR_LEN);
  47. buf.writeUint32(iaid_);
  48. buf.writeUint32(t1_);
  49. buf.writeUint32(t2_);
  50. packOptions(buf);
  51. }
  52. void Option6IA::unpack(OptionBufferConstIter begin,
  53. OptionBufferConstIter end) {
  54. // IA_NA and IA_PD have 12 bytes content (iaid, t1, t2 fields)
  55. // followed by 0 or more sub-options.
  56. if (distance(begin, end) < OPTION6_IA_LEN) {
  57. isc_throw(OutOfRange, "Option " << type_ << " truncated");
  58. }
  59. iaid_ = readUint32( &(*begin) );
  60. begin += sizeof(uint32_t);
  61. t1_ = readUint32( &(*begin) );
  62. begin += sizeof(uint32_t);
  63. t2_ = readUint32( &(*begin) );
  64. begin += sizeof(uint32_t);
  65. unpackOptions(OptionBuffer(begin, end));
  66. }
  67. std::string Option6IA::toText(int indent /* = 0*/) {
  68. stringstream tmp;
  69. for (int i=0; i<indent; i++)
  70. tmp << " ";
  71. tmp << "type=" << type_;
  72. switch (type_) {
  73. case D6O_IA_NA:
  74. tmp << "(IA_NA)";
  75. break;
  76. case D6O_IA_PD:
  77. tmp << "(IA_PD)";
  78. break;
  79. default:
  80. tmp << "(unknown)";
  81. }
  82. tmp << " iaid=" << iaid_ << ", t1=" << t1_ << ", t2=" << t2_
  83. << " " << options_.size() << " sub-options:" << endl;
  84. for (OptionCollection::const_iterator opt=options_.begin();
  85. opt!=options_.end();
  86. ++opt) {
  87. tmp << (*opt).second->toText(indent+2);
  88. }
  89. return tmp.str();
  90. }
  91. uint16_t Option6IA::len() {
  92. uint16_t length = OPTION6_HDR_LEN /*header (4)*/ +
  93. OPTION6_IA_LEN /* option content (12) */;
  94. // length of all suboptions
  95. for (Option::OptionCollection::iterator it = options_.begin();
  96. it != options_.end();
  97. ++it) {
  98. length += (*it).second->len();
  99. }
  100. return (length);
  101. }
  102. } // end of isc::dhcp namespace
  103. } // end of isc namespace