Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
ISC Open Source Projects
Kea
Commits
21a15e9e
Commit
21a15e9e
authored
Mar 24, 2014
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[3360] Implemented the CSV lease file parser for DHCPv4.
parent
587f21a5
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
695 additions
and
42 deletions
+695
-42
src/lib/dhcp/duid.cc
src/lib/dhcp/duid.cc
+33
-24
src/lib/dhcp/duid.h
src/lib/dhcp/duid.h
+35
-11
src/lib/dhcp/hwaddr.cc
src/lib/dhcp/hwaddr.cc
+37
-3
src/lib/dhcp/hwaddr.h
src/lib/dhcp/hwaddr.h
+29
-3
src/lib/dhcp/tests/duid_unittest.cc
src/lib/dhcp/tests/duid_unittest.cc
+32
-0
src/lib/dhcp/tests/hwaddr_unittest.cc
src/lib/dhcp/tests/hwaddr_unittest.cc
+26
-1
src/lib/dhcpsrv/Makefile.am
src/lib/dhcpsrv/Makefile.am
+1
-0
src/lib/dhcpsrv/csv_lease_file4.cc
src/lib/dhcpsrv/csv_lease_file4.cc
+178
-0
src/lib/dhcpsrv/csv_lease_file4.h
src/lib/dhcpsrv/csv_lease_file4.h
+153
-0
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/Makefile.am
+1
-0
src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
+166
-0
src/lib/dhcpsrv/tests/testdata/leases4_0.csv
src/lib/dhcpsrv/tests/testdata/leases4_0.csv
+4
-0
No files found.
src/lib/dhcp/duid.cc
View file @
21a15e9e
...
...
@@ -49,24 +49,8 @@ DUID::DUID(const uint8_t* data, size_t len) {
duid_
=
std
::
vector
<
uint8_t
>
(
data
,
data
+
len
);
}
const
std
::
vector
<
uint8_t
>&
DUID
::
getDuid
()
const
{
return
(
duid_
);
}
DUID
::
DUIDType
DUID
::
getType
()
const
{
if
(
duid_
.
size
()
<
2
)
{
return
(
DUID_UNKNOWN
);
}
uint16_t
type
=
(
duid_
[
0
]
<<
8
)
+
duid_
[
1
];
if
(
type
<
DUID_MAX
)
{
return
(
static_cast
<
DUID
::
DUIDType
>
(
type
));
}
else
{
return
(
DUID_UNKNOWN
);
}
}
DUID
DUID
::
fromText
(
const
std
::
string
&
text
)
{
std
::
vector
<
uint8_t
>
DUID
::
decode
(
const
std
::
string
&
text
)
{
/// @todo optimize stream operations here.
std
::
vector
<
std
::
string
>
split_text
;
boost
::
split
(
split_text
,
text
,
boost
::
is_any_of
(
":"
),
...
...
@@ -78,22 +62,41 @@ DUID::fromText(const std::string& text) {
s
<<
"0"
;
}
else
if
(
split_text
[
i
].
size
()
>
2
)
{
isc_throw
(
isc
::
BadValue
,
"invalid
DUID
'"
<<
text
<<
"'"
);
isc_throw
(
isc
::
BadValue
,
"invalid
identifier
'"
<<
text
<<
"'"
);
}
s
<<
split_text
[
i
];
}
if
(
s
.
str
().
empty
())
{
isc_throw
(
isc
::
BadValue
,
"empty DUID is not allowed"
);
}
std
::
vector
<
uint8_t
>
binary
;
try
{
util
::
encode
::
decodeHex
(
s
.
str
(),
binary
);
}
catch
(
const
Exception
&
ex
)
{
isc_throw
(
isc
::
BadValue
,
"failed to create
DUID
from text '"
isc_throw
(
isc
::
BadValue
,
"failed to create
identifier
from text '"
<<
text
<<
"': "
<<
ex
.
what
());
}
return
DUID
(
&
binary
[
0
],
binary
.
size
());
return
(
binary
);
}
const
std
::
vector
<
uint8_t
>&
DUID
::
getDuid
()
const
{
return
(
duid_
);
}
DUID
::
DUIDType
DUID
::
getType
()
const
{
if
(
duid_
.
size
()
<
2
)
{
return
(
DUID_UNKNOWN
);
}
uint16_t
type
=
(
duid_
[
0
]
<<
8
)
+
duid_
[
1
];
if
(
type
<
DUID_MAX
)
{
return
(
static_cast
<
DUID
::
DUIDType
>
(
type
));
}
else
{
return
(
DUID_UNKNOWN
);
}
}
DUID
DUID
::
fromText
(
const
std
::
string
&
text
)
{
std
::
vector
<
uint8_t
>
binary
=
decode
(
text
);
return
DUID
(
binary
);
}
std
::
string
DUID
::
toText
()
const
{
...
...
@@ -152,6 +155,12 @@ std::string ClientId::toText() const {
return
(
DUID
::
toText
());
}
ClientIdPtr
ClientId
::
fromText
(
const
std
::
string
&
text
)
{
std
::
vector
<
uint8_t
>
binary
=
decode
(
text
);
return
(
ClientIdPtr
(
new
ClientId
(
binary
)));
}
// Compares two client-ids
bool
ClientId
::
operator
==
(
const
ClientId
&
other
)
const
{
return
(
this
->
duid_
==
other
.
duid_
);
...
...
src/lib/dhcp/duid.h
View file @
21a15e9e
...
...
@@ -72,13 +72,7 @@ class DUID {
/// @brief Create DUID from the textual format.
///
/// This static function parses a DUID specified in the textual format.
/// The format being parsed should match the DUID representation returned
/// by the @c DUID::toText method, i.e. the pairs of hexadecimal digits
/// representing bytes of DUID must be separated by colons. Usually the
/// single byte is represented by two hexadecimal digits. However, this
/// function allows one digit per byte. In this case, a zero is prepended
/// before the conversion. For example, a DUID 0:1:2::4:5 equals to
/// 00:01:02:00:04:05.
/// Internally it uses @c DUID::decode to parse the DUID.
///
/// @param text DUID in the hexadecimal format with digits representing
/// individual bytes separated by colons.
...
...
@@ -96,6 +90,23 @@ class DUID {
bool
operator
!=
(
const
DUID
&
other
)
const
;
protected:
/// @brief Decodes the textual format of the DUID.
///
/// The format being parsed should match the DUID representation returned
/// by the @c DUID::toText method, i.e. the pairs of hexadecimal digits
/// representing bytes of DUID must be separated by colons. Usually the
/// single byte is represented by two hexadecimal digits. However, this
/// function allows one digit per byte. In this case, a zero is prepended
/// before the conversion. For example, a DUID 0:1:2::4:5 equals to
/// 00:01:02:00:04:05.
///
/// @param text DUID in the hexadecimal format with digits representing
/// individual bytes separated by colons.
///
/// @throw isc::BadValue if parsing the DUID failed.
static
std
::
vector
<
uint8_t
>
decode
(
const
std
::
string
&
text
);
/// The actual content of the DUID
std
::
vector
<
uint8_t
>
duid_
;
};
...
...
@@ -103,7 +114,10 @@ class DUID {
/// @brief Shared pointer to a DUID
typedef
boost
::
shared_ptr
<
DUID
>
DuidPtr
;
/// @brief Forward declaration to the @c ClientId class.
class
ClientId
;
/// @brief Shared pointer to a Client ID.
typedef
boost
::
shared_ptr
<
ClientId
>
ClientIdPtr
;
/// @brief Holds Client identifier or client IPv4 address
///
...
...
@@ -147,6 +161,19 @@ public:
/// @brief Returns textual representation of a DUID (e.g. 00:01:02:03:ff)
std
::
string
toText
()
const
;
/// @brief Create client identifier from the textual format.
///
/// This static function creates the instance of the @c ClientId from the
/// textual format. Internally it calls @c DUID::fromText. The format of
/// the input must match the format of the DUID in @c DUID::fromText.
///
/// @param text Client identifier in the textual format.
///
/// @return Pointer to the instance of the @c ClientId.
/// @throw isc::BadValue if parsing the client identifier failed.
/// @throw isc::OutOfRange if the client identifier is truncated.
static
ClientIdPtr
fromText
(
const
std
::
string
&
text
);
/// @brief Compares two client-ids for equality
bool
operator
==
(
const
ClientId
&
other
)
const
;
...
...
@@ -154,9 +181,6 @@ public:
bool
operator
!=
(
const
ClientId
&
other
)
const
;
};
/// @brief Shared pointer to a Client ID.
typedef
boost
::
shared_ptr
<
ClientId
>
ClientIdPtr
;
};
// end of isc::dhcp namespace
};
// end of isc namespace
...
...
src/lib/dhcp/hwaddr.cc
View file @
21a15e9e
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012
-2014
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -15,6 +15,10 @@
#include <dhcp/hwaddr.h>
#include <dhcp/dhcp4.h>
#include <exceptions/exceptions.h>
#include <util/encode/hex.h>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/constants.hpp>
#include <boost/algorithm/string/split.hpp>
#include <iomanip>
#include <sstream>
#include <vector>
...
...
@@ -42,9 +46,11 @@ HWAddr::HWAddr(const std::vector<uint8_t>& hwaddr, uint8_t htype)
}
}
std
::
string
HWAddr
::
toText
()
const
{
std
::
string
HWAddr
::
toText
(
bool
include_htype
)
const
{
std
::
stringstream
tmp
;
tmp
<<
"hwtype="
<<
static_cast
<
int
>
(
htype_
)
<<
" "
;
if
(
include_htype
)
{
tmp
<<
"hwtype="
<<
static_cast
<
int
>
(
htype_
)
<<
" "
;
}
tmp
<<
std
::
hex
;
bool
delim
=
false
;
for
(
std
::
vector
<
uint8_t
>::
const_iterator
it
=
hwaddr_
.
begin
();
...
...
@@ -58,6 +64,34 @@ std::string HWAddr::toText() const {
return
(
tmp
.
str
());
}
HWAddr
HWAddr
::
fromText
(
const
std
::
string
&
text
)
{
/// @todo optimize stream operations here.
std
::
vector
<
std
::
string
>
split_text
;
boost
::
split
(
split_text
,
text
,
boost
::
is_any_of
(
":"
),
boost
::
algorithm
::
token_compress_on
);
std
::
ostringstream
s
;
for
(
size_t
i
=
0
;
i
<
split_text
.
size
();
++
i
)
{
if
(
split_text
[
i
].
size
()
==
1
)
{
s
<<
"0"
;
}
else
if
(
split_text
[
i
].
size
()
>
2
)
{
isc_throw
(
isc
::
BadValue
,
"invalid hwaddr '"
<<
text
<<
"'"
);
}
s
<<
split_text
[
i
];
}
std
::
vector
<
uint8_t
>
binary
;
try
{
util
::
encode
::
decodeHex
(
s
.
str
(),
binary
);
}
catch
(
const
Exception
&
ex
)
{
isc_throw
(
isc
::
BadValue
,
"failed to create hwaddr from text '"
<<
text
<<
"': "
<<
ex
.
what
());
}
return
(
HWAddr
(
binary
,
HTYPE_ETHER
));
}
bool
HWAddr
::
operator
==
(
const
HWAddr
&
other
)
const
{
return
((
this
->
htype_
==
other
.
htype_
)
&&
(
this
->
hwaddr_
==
other
.
hwaddr_
));
...
...
src/lib/dhcp/hwaddr.h
View file @
21a15e9e
// Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2013
-2014
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -54,8 +54,34 @@ public:
// Hardware type
uint8_t
htype_
;
/// @brief Returns textual representation of a client-id (e.g. 00:01:02:03)
std
::
string
toText
()
const
;
/// @brief Returns textual representation of a hardware address
/// (e.g. 00:01:02:03:04:05)
///
/// @param include_htype Boolean value which controls whether the hardware
/// type is included in the returned string (true), or not (false).
///
/// @return Hardware address in the textual format.
std
::
string
toText
(
bool
include_htype
=
true
)
const
;
/// @brief Creates instance of the hardware address from textual format.
///
/// This function parses HW address specified as text and creates the
/// corresponding @c HWAddr instance. The hexadecimal digits representing
/// individual bytes of the hardware address should be separated with
/// colons. Typically, two digits per byte are used. However, this function
/// allows for 1 digit per HW address byte. In this case, the digit is
/// prepended with '0' during conversion to binary value.
///
/// This function can be used to perform a reverse operation to the
/// @c HWAddr::toText(false).
///
/// The instance created by this function sets HTYPE_ETHER as a hardware
/// type.
///
/// @param text HW address in the textual format.
///
/// @return Instance of the HW address created from text.
static
HWAddr
fromText
(
const
std
::
string
&
text
);
/// @brief Compares two hardware addresses for equality
bool
operator
==
(
const
HWAddr
&
other
)
const
;
...
...
src/lib/dhcp/tests/duid_unittest.cc
View file @
21a15e9e
...
...
@@ -280,4 +280,36 @@ TEST(ClientIdTest, toText) {
EXPECT_EQ
(
"00:01:02:03:04:ff:fe"
,
clientid
.
toText
());
}
// This test checks that the ClientId instance can be created from the textual
// format and that error is reported if the textual format is invalid.
TEST
(
ClientIdTest
,
fromText
)
{
ClientIdPtr
cid
;
// ClientId with only decimal digits.
ASSERT_NO_THROW
(
cid
=
ClientId
::
fromText
(
"00:01:02:03:04:05:06"
)
);
EXPECT_EQ
(
"00:01:02:03:04:05:06"
,
cid
->
toText
());
// ClientId with some hexadecimal digits (upper case and lower case).
ASSERT_NO_THROW
(
cid
=
ClientId
::
fromText
(
"00:aa:bb:CD:ee:EF:ab"
)
);
EXPECT_EQ
(
"00:aa:bb:cd:ee:ef:ab"
,
cid
->
toText
());
// ClientId with one digit for a particular byte.
ASSERT_NO_THROW
(
cid
=
ClientId
::
fromText
(
"00:a:bb:D:ee:EF:ab"
)
);
EXPECT_EQ
(
"00:0a:bb:0d:ee:ef:ab"
,
cid
->
toText
());
// Repeated colon sign in the ClientId should be ignored.
ASSERT_NO_THROW
(
cid
=
ClientId
::
fromText
(
"00::bb:D:ee:EF:ab"
)
);
EXPECT_EQ
(
"00:bb:0d:ee:ef:ab"
,
cid
->
toText
());
// ClientId with excessive number of digits for one of the bytes.
EXPECT_THROW
(
cid
=
ClientId
::
fromText
(
"00:01:021:03:04:05:06"
),
isc
::
BadValue
);
}
}
// end of anonymous namespace
src/lib/dhcp/tests/hwaddr_unittest.cc
View file @
21a15e9e
// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
// Copyright (C) 2012
, 2014
Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
...
...
@@ -108,6 +108,9 @@ TEST(HWAddrTest, toText) {
EXPECT_EQ
(
"hwtype=15 00:01:02:03:04:05"
,
hw
->
toText
());
// In some cases we don't want htype value to be included. Check that
// it can be forced.
EXPECT_EQ
(
"00:01:02:03:04:05"
,
hw
->
toText
(
false
));
}
TEST
(
HWAddrTest
,
stringConversion
)
{
...
...
@@ -131,5 +134,27 @@ TEST(HWAddrTest, stringConversion) {
EXPECT_EQ
(
std
::
string
(
"hwtype=1 c3:07:a2:e8:42"
),
result
);
}
// Checks that the HW address can be created from the textual format.
TEST
(
HWAddrTest
,
fromText
)
{
scoped_ptr
<
HWAddr
>
hwaddr
;
// Create HWAddr from text.
ASSERT_NO_THROW
(
hwaddr
.
reset
(
new
HWAddr
(
HWAddr
::
fromText
(
"00:01:A:bc:d:67"
)));
);
EXPECT_EQ
(
"00:01:0a:bc:0d:67"
,
hwaddr
->
toText
(
false
));
// HWAddr class should allow empty address.
ASSERT_NO_THROW
(
hwaddr
.
reset
(
new
HWAddr
(
HWAddr
::
fromText
(
""
)));
);
EXPECT_TRUE
(
hwaddr
->
toText
(
false
).
empty
());
// There should be no more than two digits per byte of the HW addr.
EXPECT_THROW
(
hwaddr
.
reset
(
new
HWAddr
(
HWAddr
::
fromText
(
"00:01:00A:bc:0d:67"
))),
isc
::
BadValue
);
}
}
// end of anonymous namespace
src/lib/dhcpsrv/Makefile.am
View file @
21a15e9e
...
...
@@ -39,6 +39,7 @@ libb10_dhcpsrv_la_SOURCES =
libb10_dhcpsrv_la_SOURCES
+=
addr_utilities.cc addr_utilities.h
libb10_dhcpsrv_la_SOURCES
+=
alloc_engine.cc alloc_engine.h
libb10_dhcpsrv_la_SOURCES
+=
callout_handle_store.h
libb10_dhcpsrv_la_SOURCES
+=
csv_lease_file4.cc csv_lease_file4.h
libb10_dhcpsrv_la_SOURCES
+=
csv_lease_file6.cc csv_lease_file6.h
libb10_dhcpsrv_la_SOURCES
+=
d2_client_cfg.cc d2_client_cfg.h
libb10_dhcpsrv_la_SOURCES
+=
d2_client_mgr.cc d2_client_mgr.h
...
...
src/lib/dhcpsrv/csv_lease_file4.cc
0 → 100644
View file @
21a15e9e
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#include <dhcpsrv/csv_lease_file4.h>
using
namespace
isc
::
asiolink
;
using
namespace
isc
::
util
;
namespace
isc
{
namespace
dhcp
{
CSVLeaseFile4
::
CSVLeaseFile4
(
const
std
::
string
&
filename
)
:
CSVFile
(
filename
)
{
initColumns
();
}
void
CSVLeaseFile4
::
append
(
const
Lease4
&
lease
)
const
{
CSVRow
row
(
getColumnCount
());
row
.
writeAt
(
getColumnIndex
(
"address"
),
lease
.
addr_
.
toText
());
HWAddr
hwaddr
(
lease
.
hwaddr_
,
HTYPE_ETHER
);
row
.
writeAt
(
getColumnIndex
(
"hwaddr"
),
hwaddr
.
toText
(
false
));
// Client id may be unset (NULL).
if
(
lease
.
client_id_
)
{
row
.
writeAt
(
getColumnIndex
(
"client_id"
),
lease
.
client_id_
->
toText
());
}
row
.
writeAt
(
getColumnIndex
(
"valid_lifetime"
),
lease
.
valid_lft_
);
row
.
writeAt
(
getColumnIndex
(
"expire"
),
lease
.
cltt_
+
lease
.
valid_lft_
);
row
.
writeAt
(
getColumnIndex
(
"subnet_id"
),
lease
.
subnet_id_
);
row
.
writeAt
(
getColumnIndex
(
"fqdn_fwd"
),
lease
.
fqdn_fwd_
);
row
.
writeAt
(
getColumnIndex
(
"fqdn_rev"
),
lease
.
fqdn_rev_
);
row
.
writeAt
(
getColumnIndex
(
"hostname"
),
lease
.
hostname_
);
CSVFile
::
append
(
row
);
}
bool
CSVLeaseFile4
::
next
(
Lease4Ptr
&
lease
)
{
// We will return NULL pointer if the lease is not read.
lease
.
reset
();
// Get the row of CSV values.
CSVRow
row
;
CSVFile
::
next
(
row
);
// The empty row signals EOF.
if
(
row
==
CSVFile
::
EMPTY_ROW
())
{
return
(
true
);
}
// Try to create a lease from the values read. This may easily result in
// exception. We don't want this function to throw exceptions, so we catch
// them all and rather return the false value.
try
{
// Get client id. It is possible that the client id is empty and the
// returned pointer is NULL. This is ok, but if the client id is NULL,
// we need to be careful to not use the NULL pointer.
ClientIdPtr
client_id
=
readClientId
(
row
);
std
::
vector
<
uint8_t
>
client_id_vec
;
if
(
client_id
)
{
client_id_vec
=
client_id
->
getClientId
();
}
size_t
client_id_len
=
client_id_vec
.
empty
()
?
0
:
client_id_vec
.
size
();
// Get the HW address. It should never be empty and the readHWAddr checks
// that.
HWAddr
hwaddr
=
readHWAddr
(
row
);
lease
.
reset
(
new
Lease4
(
readAddress
(
row
),
&
hwaddr
.
hwaddr_
[
0
],
hwaddr
.
hwaddr_
.
size
(),
client_id_vec
.
empty
()
?
NULL
:
&
client_id_vec
[
0
],
client_id_len
,
readValid
(
row
),
0
,
0
,
// t1, t2 = 0
readCltt
(
row
),
readSubnetID
(
row
),
readFqdnFwd
(
row
),
readFqdnRev
(
row
),
readHostname
(
row
)));
}
catch
(
std
::
exception
&
ex
)
{
// The lease might have been created, so let's set it back to NULL to
// signal that lease hasn't been parsed.
lease
.
reset
();
setReadMsg
(
ex
.
what
());
return
(
false
);
}
return
(
true
);
}
void
CSVLeaseFile4
::
initColumns
()
{
addColumn
(
"address"
);
addColumn
(
"hwaddr"
);
addColumn
(
"client_id"
);
addColumn
(
"valid_lifetime"
);
addColumn
(
"expire"
);
addColumn
(
"subnet_id"
);
addColumn
(
"fqdn_fwd"
);
addColumn
(
"fqdn_rev"
);
addColumn
(
"hostname"
);
}
IOAddress
CSVLeaseFile4
::
readAddress
(
const
CSVRow
&
row
)
{
IOAddress
address
(
row
.
readAt
(
getColumnIndex
(
"address"
)));
return
(
address
);
}
HWAddr
CSVLeaseFile4
::
readHWAddr
(
const
CSVRow
&
row
)
{
HWAddr
hwaddr
=
HWAddr
::
fromText
(
row
.
readAt
(
getColumnIndex
(
"hwaddr"
)));
if
(
hwaddr
.
hwaddr_
.
empty
())
{
isc_throw
(
isc
::
BadValue
,
"hardware address in the lease file"
" must not be empty"
);
}
return
(
hwaddr
);
}
ClientIdPtr
CSVLeaseFile4
::
readClientId
(
const
CSVRow
&
row
)
{
std
::
string
client_id
=
row
.
readAt
(
getColumnIndex
(
"client_id"
));
// NULL client ids are allowed in DHCPv4.
if
(
client_id
.
empty
())
{
return
(
ClientIdPtr
());
}
ClientIdPtr
cid
=
ClientId
::
fromText
(
client_id
);
return
(
cid
);
}
uint32_t
CSVLeaseFile4
::
readValid
(
const
CSVRow
&
row
)
{
uint32_t
valid
=
row
.
readAndConvertAt
<
uint32_t
>
(
getColumnIndex
(
"valid_lifetime"
));
return
(
valid
);
}
time_t
CSVLeaseFile4
::
readCltt
(
const
CSVRow
&
row
)
{
uint32_t
cltt
=
row
.
readAndConvertAt
<
uint32_t
>
(
getColumnIndex
(
"expire"
))
-
readValid
(
row
);
return
(
cltt
);
}
SubnetID
CSVLeaseFile4
::
readSubnetID
(
const
CSVRow
&
row
)
{
SubnetID
subnet_id
=
row
.
readAndConvertAt
<
SubnetID
>
(
getColumnIndex
(
"subnet_id"
));
return
(
subnet_id
);
}
bool
CSVLeaseFile4
::
readFqdnFwd
(
const
CSVRow
&
row
)
{
bool
fqdn_fwd
=
row
.
readAndConvertAt
<
bool
>
(
getColumnIndex
(
"fqdn_fwd"
));
return
(
fqdn_fwd
);
}
bool
CSVLeaseFile4
::
readFqdnRev
(
const
CSVRow
&
row
)
{
bool
fqdn_rev
=
row
.
readAndConvertAt
<
bool
>
(
getColumnIndex
(
"fqdn_rev"
));
return
(
fqdn_rev
);
}
std
::
string
CSVLeaseFile4
::
readHostname
(
const
CSVRow
&
row
)
{
std
::
string
hostname
=
row
.
readAt
(
getColumnIndex
(
"hostname"
));
return
(
hostname
);
}
}
// end of namespace isc::dhcp
}
// end of namespace isc
src/lib/dhcpsrv/csv_lease_file4.h
0 → 100644
View file @
21a15e9e
// Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
#ifndef CSV_LEASE_FILE4_H
#define CSV_LEASE_FILE4_H
#include <asiolink/io_address.h>
#include <dhcp/duid.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/subnet.h>
#include <util/csv_file.h>
#include <stdint.h>
#include <string>
#include <time.h>
namespace
isc
{
namespace
dhcp
{
/// @brief Provides methods to access CSV file with DHCPv4 leases.
///
/// This class contains methods customized to read DHCPv4 leases from the CSV
/// file. It expects that the CSV file being parsed, contains the set of columns
/// with well known names (initialized in the class constructor).
///
/// @todo This class doesn't validate the lease values read from the file.
/// The @c Lease4 is a structure that should be itself responsible for this
/// validation (see http://bind10.isc.org/ticket/2405). However, when #2405
/// is implemented, the @c next function may need to be updated to use the
/// validation capablity of @c Lease4.
class
CSVLeaseFile4
:
public
isc
::
util
::
CSVFile
{
public:
/// @brief Constructor.
///
/// Initializes columns of the lease file.
///
/// @param filename Name of the lease file.
CSVLeaseFile4
(
const
std
::
string
&
filename
);
/// @brief Appends the lease record to the CSV file.
///
/// This function doesn't throw exceptions itself. In theory, exceptions
/// are possible when the index of the indexes of the values being written
/// to the file are invalid. However, this would have been a programming
/// error.
///
/// @param lease Structure representing a DHCPv4 lease.
void
append
(
const
Lease4
&
lease
)
const
;
/// @brief Reads next lease from the CSV file.
///
/// If this function hits an error during lease read, it sets the error
/// message using @c CSVFile::setReadMsg and returns false. The error
/// string may be read using @c CSVFile::getReadMsg.
///
/// This function is exception safe.
///
/// @param [out] lease Pointer to the lease read from CSV file or
/// NULL pointer if lease hasn't been read.
///
/// @return Boolean value indicating that the new lease has been
/// read from the CSV file (if true), or that the error has occurred
/// (false).
///
/// @todo Make sure that the values read from the file are correct.
/// The appropriate @c Lease4 validation mechanism should be used once