option6_ia.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // Copyright (C) 2011 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 <arpa/inet.h>
  16. #include <sstream>
  17. #include "exceptions/exceptions.h"
  18. #include "dhcp/libdhcp.h"
  19. #include "dhcp/option6_ia.h"
  20. #include "dhcp/dhcp6.h"
  21. #include "util/io_utilities.h"
  22. using namespace std;
  23. using namespace isc;
  24. using namespace isc::dhcp;
  25. using namespace isc::util;
  26. Option6IA::Option6IA(unsigned short type, unsigned int iaid)
  27. :Option(Option::V6, type), iaid_(iaid) {
  28. }
  29. Option6IA::Option6IA(unsigned short type,
  30. const boost::shared_array<uint8_t>& buf,
  31. unsigned int buf_len,
  32. unsigned int offset,
  33. unsigned int option_len)
  34. :Option(Option::V6, type) {
  35. unpack(buf, buf_len, offset, option_len);
  36. }
  37. unsigned int
  38. Option6IA::pack(boost::shared_array<uint8_t>& buf,
  39. unsigned int buf_len,
  40. unsigned int offset) {
  41. if (offset + len() > buf_len) {
  42. isc_throw(OutOfRange, "Failed to pack IA option: len=" << len()
  43. << ", buffer=" << buf_len << ": too small buffer.");
  44. }
  45. if (len() < 16 ) {
  46. isc_throw(OutOfRange, "Attempt to build malformed IA option: len="
  47. << len() << " is too small (at least 16 is required).");
  48. }
  49. uint8_t* ptr = &buf[offset];
  50. ptr = writeUint16(type_, ptr);
  51. ptr = writeUint16(len() - OPTION6_HDR_LEN, ptr);
  52. offset += OPTION6_HDR_LEN;
  53. ptr = writeUint32(iaid_, ptr);
  54. ptr = writeUint32(t1_, ptr);
  55. ptr = writeUint32(t2_, ptr);
  56. offset += OPTION6_IA_LEN;
  57. offset = LibDHCP::packOptions6(buf, buf_len, offset, options_);
  58. return offset;
  59. }
  60. unsigned int
  61. Option6IA::unpack(const boost::shared_array<uint8_t>& buf,
  62. unsigned int buf_len,
  63. unsigned int offset,
  64. unsigned int parse_len) {
  65. if ( parse_len < OPTION6_IA_LEN || offset + OPTION6_IA_LEN > buf_len) {
  66. isc_throw(OutOfRange, "Option " << type_ << " truncated");
  67. }
  68. iaid_ = readUint32(&buf[offset]);
  69. offset += sizeof(uint32_t);
  70. t1_ = readUint32(&buf[offset]);
  71. offset += sizeof(uint32_t);
  72. t2_ = readUint32(&buf[offset]);
  73. offset += sizeof(uint32_t);
  74. offset = LibDHCP::unpackOptions6(buf, buf_len, offset,
  75. parse_len - OPTION6_IA_LEN, options_);
  76. return (offset);
  77. }
  78. std::string Option6IA::toText(int indent /* = 0*/) {
  79. stringstream tmp;
  80. for (int i=0; i<indent; i++)
  81. tmp << " ";
  82. tmp << "type=" << type_;
  83. switch (type_) {
  84. case D6O_IA_NA:
  85. tmp << "(IA_NA)";
  86. break;
  87. case D6O_IA_PD:
  88. tmp << "(IA_PD)";
  89. break;
  90. default:
  91. tmp << "(unknown)";
  92. }
  93. tmp << " iaid=" << iaid_ << ", t1=" << t1_ << ", t2=" << t2_
  94. << " " << options_.size() << " sub-options:" << endl;
  95. for (Option6Collection::const_iterator opt=options_.begin();
  96. opt!=options_.end();
  97. ++opt) {
  98. tmp << (*opt).second->toText(indent+2);
  99. }
  100. return tmp.str();
  101. }
  102. unsigned short Option6IA::len() {
  103. unsigned short length = OPTION6_HDR_LEN /*header (4)*/ +
  104. OPTION6_IA_LEN /* option content (12) */;
  105. // length of all suboptions
  106. for (Option::Option6Collection::iterator it = options_.begin();
  107. it != options_.end();
  108. ++it) {
  109. length += (*it).second->len();
  110. }
  111. return (length);
  112. }