csv_lease_file6.cc 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. // Copyright (C) 2014 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 <dhcpsrv/dhcpsrv_log.h>
  15. #include <dhcpsrv/csv_lease_file6.h>
  16. using namespace isc::asiolink;
  17. using namespace isc::util;
  18. namespace isc {
  19. namespace dhcp {
  20. CSVLeaseFile6::CSVLeaseFile6(const std::string& filename)
  21. : CSVFile(filename) {
  22. initColumns();
  23. }
  24. void
  25. CSVLeaseFile6::append(const Lease6& lease) const {
  26. CSVRow row(getColumnCount());
  27. row.writeAt(getColumnIndex("address"), lease.addr_.toText());
  28. row.writeAt(getColumnIndex("duid"), lease.duid_->toText());
  29. row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
  30. row.writeAt(getColumnIndex("expire"), lease.cltt_ + lease.valid_lft_);
  31. row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
  32. row.writeAt(getColumnIndex("pref_lifetime"), lease.preferred_lft_);
  33. row.writeAt(getColumnIndex("lease_type"), lease.type_);
  34. row.writeAt(getColumnIndex("iaid"), lease.iaid_);
  35. row.writeAt(getColumnIndex("prefix_len"),
  36. static_cast<int>(lease.prefixlen_));
  37. row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
  38. row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
  39. row.writeAt(getColumnIndex("hostname"), lease.hostname_);
  40. if (lease.hwaddr_) {
  41. // We may not have hardware information
  42. row.writeAt(getColumnIndex("hwaddr"), lease.hwaddr_->toText(false));
  43. }
  44. CSVFile::append(row);
  45. }
  46. bool
  47. CSVLeaseFile6::next(Lease6Ptr& lease) {
  48. // Read the CSV row and try to create a lease from the values read.
  49. // This may easily result in exception. We don't want this function
  50. // to throw exceptions, so we catch them all and rather return the
  51. // false value.
  52. try {
  53. // Get the row of CSV values.
  54. CSVRow row;
  55. CSVFile::next(row);
  56. // The empty row signals EOF.
  57. if (row == CSVFile::EMPTY_ROW()) {
  58. lease.reset();
  59. return (true);
  60. }
  61. lease.reset(new Lease6(readType(row), readAddress(row), readDUID(row),
  62. readIAID(row), readPreferred(row),
  63. readValid(row), 0, 0, // t1, t2 = 0
  64. readSubnetID(row),
  65. readHWAddr(row),
  66. readPrefixLen(row)));
  67. lease->cltt_ = readCltt(row);
  68. lease->fqdn_fwd_ = readFqdnFwd(row);
  69. lease->fqdn_rev_ = readFqdnRev(row);
  70. lease->hostname_ = readHostname(row);
  71. } catch (std::exception& ex) {
  72. // The lease might have been created, so let's set it back to NULL to
  73. // signal that lease hasn't been parsed.
  74. lease.reset();
  75. setReadMsg(ex.what());
  76. return (false);
  77. }
  78. return (true);
  79. }
  80. void
  81. CSVLeaseFile6::initColumns() {
  82. addColumn("address");
  83. addColumn("duid");
  84. addColumn("valid_lifetime");
  85. addColumn("expire");
  86. addColumn("subnet_id");
  87. addColumn("pref_lifetime");
  88. addColumn("lease_type");
  89. addColumn("iaid");
  90. addColumn("prefix_len");
  91. addColumn("fqdn_fwd");
  92. addColumn("fqdn_rev");
  93. addColumn("hostname");
  94. addColumn("hwaddr");
  95. }
  96. Lease::Type
  97. CSVLeaseFile6::readType(const CSVRow& row) {
  98. return (static_cast<Lease::Type>
  99. (row.readAndConvertAt<int>(getColumnIndex("lease_type"))));
  100. }
  101. IOAddress
  102. CSVLeaseFile6::readAddress(const CSVRow& row) {
  103. IOAddress address(row.readAt(getColumnIndex("address")));
  104. return (address);
  105. }
  106. DuidPtr
  107. CSVLeaseFile6::readDUID(const util::CSVRow& row) {
  108. DuidPtr duid(new DUID(DUID::fromText(row.readAt(getColumnIndex("duid")))));
  109. return (duid);
  110. }
  111. uint32_t
  112. CSVLeaseFile6::readIAID(const CSVRow& row) {
  113. uint32_t iaid = row.readAndConvertAt<uint32_t>(getColumnIndex("iaid"));
  114. return (iaid);
  115. }
  116. uint32_t
  117. CSVLeaseFile6::readPreferred(const CSVRow& row) {
  118. uint32_t pref =
  119. row.readAndConvertAt<uint32_t>(getColumnIndex("pref_lifetime"));
  120. return (pref);
  121. }
  122. uint32_t
  123. CSVLeaseFile6::readValid(const CSVRow& row) {
  124. uint32_t valid =
  125. row.readAndConvertAt<uint32_t>(getColumnIndex("valid_lifetime"));
  126. return (valid);
  127. }
  128. uint32_t
  129. CSVLeaseFile6::readCltt(const CSVRow& row) {
  130. uint32_t cltt = row.readAndConvertAt<uint32_t>(getColumnIndex("expire"))
  131. - readValid(row);
  132. return (cltt);
  133. }
  134. SubnetID
  135. CSVLeaseFile6::readSubnetID(const CSVRow& row) {
  136. SubnetID subnet_id =
  137. row.readAndConvertAt<SubnetID>(getColumnIndex("subnet_id"));
  138. return (subnet_id);
  139. }
  140. uint8_t
  141. CSVLeaseFile6::readPrefixLen(const CSVRow& row) {
  142. int prefixlen = row.readAndConvertAt<int>(getColumnIndex("prefix_len"));
  143. return (static_cast<uint8_t>(prefixlen));
  144. }
  145. bool
  146. CSVLeaseFile6::readFqdnFwd(const CSVRow& row) {
  147. bool fqdn_fwd = row.readAndConvertAt<bool>(getColumnIndex("fqdn_fwd"));
  148. return (fqdn_fwd);
  149. }
  150. bool
  151. CSVLeaseFile6::readFqdnRev(const CSVRow& row) {
  152. bool fqdn_rev = row.readAndConvertAt<bool>(getColumnIndex("fqdn_rev"));
  153. return (fqdn_rev);
  154. }
  155. std::string
  156. CSVLeaseFile6::readHostname(const CSVRow& row) {
  157. std::string hostname = row.readAt(getColumnIndex("hostname"));
  158. return (hostname);
  159. }
  160. HWAddrPtr
  161. CSVLeaseFile6::readHWAddr(const CSVRow& row) {
  162. try {
  163. const HWAddr& hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
  164. if (hwaddr.hwaddr_.empty()) {
  165. return (HWAddrPtr());
  166. }
  167. /// @todo: HWAddr returns an object, not a pointer. Without HWAddr
  168. /// refactoring, at least one copy is unavoidable.
  169. // Let's return a pointer to new freshly created copy.
  170. return (HWAddrPtr(new HWAddr(hwaddr)));
  171. } catch (const CSVFileError&) {
  172. // That's ok, we may be reading old CSV file that didn't store hwaddr
  173. return (HWAddrPtr());
  174. } catch (const BadValue& ex) {
  175. // That's worse. There was something in the file, but its conversion
  176. // to HWAddr failed. Let's log it on warning and carry on.
  177. LOG_WARN(dhcpsrv_logger, DHCPSRV_MEMFILE_READ_HWADDR_FAIL)
  178. .arg(ex.what());
  179. return (HWAddrPtr());
  180. }
  181. }
  182. bool
  183. CSVLeaseFile6::validateHeader(const isc::util::CSVRow& header) {
  184. if (!CSVFile::validateHeader(header)) {
  185. // One possible validation failure is that we're reading Kea 0.9
  186. // lease file that didn't have hwaddr column. Let's add it and
  187. // try to revalidate.
  188. isc::util::CSVRow copy = header;
  189. copy.append("hwaddr");
  190. return CSVFile::validateHeader(copy);
  191. } else {
  192. return (true);
  193. }
  194. }
  195. } // end of namespace isc::dhcp
  196. } // end of namespace isc