csv_lease_file4.cc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  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/csv_lease_file4.h>
  15. using namespace isc::asiolink;
  16. using namespace isc::util;
  17. namespace isc {
  18. namespace dhcp {
  19. CSVLeaseFile4::CSVLeaseFile4(const std::string& filename)
  20. : CSVFile(filename) {
  21. initColumns();
  22. }
  23. void
  24. CSVLeaseFile4::append(const Lease4& lease) const {
  25. CSVRow row(getColumnCount());
  26. row.writeAt(getColumnIndex("address"), lease.addr_.toText());
  27. HWAddr hwaddr(lease.hwaddr_, HTYPE_ETHER);
  28. row.writeAt(getColumnIndex("hwaddr"), hwaddr.toText(false));
  29. // Client id may be unset (NULL).
  30. if (lease.client_id_) {
  31. row.writeAt(getColumnIndex("client_id"), lease.client_id_->toText());
  32. }
  33. row.writeAt(getColumnIndex("valid_lifetime"), lease.valid_lft_);
  34. row.writeAt(getColumnIndex("expire"), lease.cltt_ + lease.valid_lft_);
  35. row.writeAt(getColumnIndex("subnet_id"), lease.subnet_id_);
  36. row.writeAt(getColumnIndex("fqdn_fwd"), lease.fqdn_fwd_);
  37. row.writeAt(getColumnIndex("fqdn_rev"), lease.fqdn_rev_);
  38. row.writeAt(getColumnIndex("hostname"), lease.hostname_);
  39. CSVFile::append(row);
  40. }
  41. bool
  42. CSVLeaseFile4::next(Lease4Ptr& lease) {
  43. // We will return NULL pointer if the lease is not read.
  44. lease.reset();
  45. // Get the row of CSV values.
  46. CSVRow row;
  47. CSVFile::next(row);
  48. // The empty row signals EOF.
  49. if (row == CSVFile::EMPTY_ROW()) {
  50. return (true);
  51. }
  52. // Try to create a lease from the values read. This may easily result in
  53. // exception. We don't want this function to throw exceptions, so we catch
  54. // them all and rather return the false value.
  55. try {
  56. // Get client id. It is possible that the client id is empty and the
  57. // returned pointer is NULL. This is ok, but if the client id is NULL,
  58. // we need to be careful to not use the NULL pointer.
  59. ClientIdPtr client_id = readClientId(row);
  60. std::vector<uint8_t> client_id_vec;
  61. if (client_id) {
  62. client_id_vec = client_id->getClientId();
  63. }
  64. size_t client_id_len = client_id_vec.empty() ? 0 : client_id_vec.size();
  65. // Get the HW address. It should never be empty and the readHWAddr checks
  66. // that.
  67. HWAddr hwaddr = readHWAddr(row);
  68. lease.reset(new Lease4(readAddress(row),
  69. &hwaddr.hwaddr_[0], hwaddr.hwaddr_.size(),
  70. client_id_vec.empty() ? NULL : &client_id_vec[0],
  71. client_id_len,
  72. readValid(row),
  73. 0, 0, // t1, t2 = 0
  74. readCltt(row),
  75. readSubnetID(row),
  76. readFqdnFwd(row),
  77. readFqdnRev(row),
  78. readHostname(row)));
  79. } catch (std::exception& ex) {
  80. // The lease might have been created, so let's set it back to NULL to
  81. // signal that lease hasn't been parsed.
  82. lease.reset();
  83. setReadMsg(ex.what());
  84. return (false);
  85. }
  86. return (true);
  87. }
  88. void
  89. CSVLeaseFile4::initColumns() {
  90. addColumn("address");
  91. addColumn("hwaddr");
  92. addColumn("client_id");
  93. addColumn("valid_lifetime");
  94. addColumn("expire");
  95. addColumn("subnet_id");
  96. addColumn("fqdn_fwd");
  97. addColumn("fqdn_rev");
  98. addColumn("hostname");
  99. }
  100. IOAddress
  101. CSVLeaseFile4::readAddress(const CSVRow& row) {
  102. IOAddress address(row.readAt(getColumnIndex("address")));
  103. return (address);
  104. }
  105. HWAddr
  106. CSVLeaseFile4::readHWAddr(const CSVRow& row) {
  107. HWAddr hwaddr = HWAddr::fromText(row.readAt(getColumnIndex("hwaddr")));
  108. if (hwaddr.hwaddr_.empty()) {
  109. isc_throw(isc::BadValue, "hardware address in the lease file"
  110. " must not be empty");
  111. }
  112. return (hwaddr);
  113. }
  114. ClientIdPtr
  115. CSVLeaseFile4::readClientId(const CSVRow& row) {
  116. std::string client_id = row.readAt(getColumnIndex("client_id"));
  117. // NULL client ids are allowed in DHCPv4.
  118. if (client_id.empty()) {
  119. return (ClientIdPtr());
  120. }
  121. ClientIdPtr cid = ClientId::fromText(client_id);
  122. return (cid);
  123. }
  124. uint32_t
  125. CSVLeaseFile4::readValid(const CSVRow& row) {
  126. uint32_t valid =
  127. row.readAndConvertAt<uint32_t>(getColumnIndex("valid_lifetime"));
  128. return (valid);
  129. }
  130. time_t
  131. CSVLeaseFile4::readCltt(const CSVRow& row) {
  132. uint32_t cltt = row.readAndConvertAt<uint32_t>(getColumnIndex("expire"))
  133. - readValid(row);
  134. return (cltt);
  135. }
  136. SubnetID
  137. CSVLeaseFile4::readSubnetID(const CSVRow& row) {
  138. SubnetID subnet_id =
  139. row.readAndConvertAt<SubnetID>(getColumnIndex("subnet_id"));
  140. return (subnet_id);
  141. }
  142. bool
  143. CSVLeaseFile4::readFqdnFwd(const CSVRow& row) {
  144. bool fqdn_fwd = row.readAndConvertAt<bool>(getColumnIndex("fqdn_fwd"));
  145. return (fqdn_fwd);
  146. }
  147. bool
  148. CSVLeaseFile4::readFqdnRev(const CSVRow& row) {
  149. bool fqdn_rev = row.readAndConvertAt<bool>(getColumnIndex("fqdn_rev"));
  150. return (fqdn_rev);
  151. }
  152. std::string
  153. CSVLeaseFile4::readHostname(const CSVRow& row) {
  154. std::string hostname = row.readAt(getColumnIndex("hostname"));
  155. return (hostname);
  156. }
  157. } // end of namespace isc::dhcp
  158. } // end of namespace isc