Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
Kea
Commits
522d27a6
Commit
522d27a6
authored
Sep 08, 2011
by
Tomek Mrugalski
🛰
Browse files
[1186] Option6_AddrLst implemented (useful for storing v6 addresses)
parent
c4291199
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp6/iface_mgr.cc
View file @
522d27a6
...
...
@@ -546,9 +546,11 @@ IfaceMgr::receive() {
// That's ugly.
// TODO add IOAddress constructor that will take struct in6_addr*
// TODO: there's from_bytes() method added in IOAddress. Use it!
inet_ntop
(
AF_INET6
,
&
to_addr
,
addr_str
,
INET6_ADDRSTRLEN
);
pkt
->
local_addr_
=
IOAddress
(
string
(
addr_str
));
// TODO: there's from_bytes() method added in IOAddress. Use it!
inet_ntop
(
AF_INET6
,
&
from
.
sin6_addr
,
addr_str
,
INET6_ADDRSTRLEN
);
pkt
->
remote_addr_
=
IOAddress
(
string
(
addr_str
));
...
...
src/lib/dhcp/Makefile.am
View file @
522d27a6
...
...
@@ -13,6 +13,7 @@ libdhcp_la_SOURCES += libdhcp.cc libdhcp.h
libdhcp_la_SOURCES
+=
option.cc option.h
libdhcp_la_SOURCES
+=
option6_ia.cc option6_ia.h
libdhcp_la_SOURCES
+=
option6_iaaddr.cc option6_iaaddr.h
libdhcp_la_SOURCES
+=
option6_addrlst.cc option6_addrlst.h
libdhcp_la_SOURCES
+=
dhcp6.h
libdhcp_la_SOURCES
+=
pkt6.cc pkt6.h
...
...
src/lib/dhcp/option6_addrlst.cc
0 → 100644
View file @
522d27a6
// Copyright (C) 2011 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
<stdint.h>
#include
<arpa/inet.h>
#include
<sstream>
#include
"exceptions/exceptions.h"
#include
"libdhcp.h"
#include
"option6_addrlst.h"
#include
"dhcp6.h"
#include
"io_address.h"
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
asiolink
;
Option6AddrLst
::
Option6AddrLst
(
unsigned
short
type
,
std
::
vector
<
isc
::
asiolink
::
IOAddress
>&
addrs
)
:
Option
(
V6
,
type
)
{
addrs_
=
addrs
;
}
Option6AddrLst
::
Option6AddrLst
(
unsigned
short
type
,
isc
::
asiolink
::
IOAddress
addr
)
:
Option
(
V6
,
type
)
{
addrs_
.
push_back
(
addr
);
}
Option6AddrLst
::
Option6AddrLst
(
unsigned
short
type
,
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
,
unsigned
int
option_len
)
:
Option
(
V6
,
type
)
{
unpack
(
buf
,
buf_len
,
offset
,
option_len
);
}
void
Option6AddrLst
::
setAddress
(
isc
::
asiolink
::
IOAddress
addr
)
{
addrs_
.
clear
();
addrs_
.
push_back
(
addr
);
}
void
Option6AddrLst
::
setAddresses
(
std
::
vector
<
isc
::
asiolink
::
IOAddress
>&
addrs
)
{
addrs_
=
addrs
;
}
unsigned
int
Option6AddrLst
::
pack
(
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
)
{
if
(
len
()
>
buf_len
)
{
isc_throw
(
OutOfRange
,
"Failed to pack IA option: len="
<<
len
()
<<
", buffer="
<<
buf_len
<<
": too small buffer."
);
}
*
(
uint16_t
*
)
&
buf
[
offset
]
=
htons
(
type_
);
offset
+=
2
;
*
(
uint16_t
*
)
&
buf
[
offset
]
=
htons
(
len
()
-
4
);
// len() returns complete option
// length. len field contains length without 4-byte option header
offset
+=
2
;
for
(
std
::
vector
<
IOAddress
>::
const_iterator
addr
=
addrs_
.
begin
();
addr
!=
addrs_
.
end
();
++
addr
)
{
memcpy
(
&
buf
[
offset
],
addr
->
getAddress
().
to_v6
().
to_bytes
().
data
(),
16
);
offset
+=
16
;
}
return
offset
;
}
unsigned
int
Option6AddrLst
::
unpack
(
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
,
unsigned
int
option_len
)
{
if
(
offset
+
option_len
>
buf_len
)
{
isc_throw
(
OutOfRange
,
"Option "
<<
type_
<<
" truncated."
);
}
if
(
option_len
%
16
)
{
isc_throw
(
OutOfRange
,
"Option "
<<
type_
<<
" malformed: len="
<<
option_len
<<
" is not divisible by 16."
);
}
while
(
option_len
>
0
)
{
addrs_
.
push_back
(
IOAddress
::
from_bytes
(
AF_INET6
,
&
buf
[
offset
]));
offset
+=
16
;
option_len
-=
16
;
}
return
offset
;
}
std
::
string
Option6AddrLst
::
toText
(
int
indent
/* =0 */
)
{
stringstream
tmp
;
for
(
int
i
=
0
;
i
<
indent
;
i
++
)
tmp
<<
" "
;
tmp
<<
"type="
<<
type_
<<
" "
<<
addrs_
.
size
()
<<
"addr(s): "
;
for
(
AddrsContainer
::
const_iterator
addr
=
addrs_
.
begin
();
addr
!=
addrs_
.
end
();
++
addr
)
{
tmp
<<
addr
->
toText
()
<<
" "
;
}
return
tmp
.
str
();
}
unsigned
short
Option6AddrLst
::
len
()
{
return
(
4
/* DHCPv6 option header len */
+
addrs_
.
size
()
*
16
);
}
src/lib/dhcp/option6_addrlst.h
0 → 100644
View file @
522d27a6
// Copyright (C) 2011 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 OPTION6_ADDRLST_H_
#define OPTION6_ADDRLST_H_
#include
<vector>
#include
"io_address.h"
#include
"option.h"
namespace
isc
{
namespace
dhcp
{
/// @brief Option class for handling list of IPv6 addresses.
///
/// This class handles a list of IPv6 addresses. An example of such option
/// is dns-servers option. It can also be used to handle single address.
///
class
Option6AddrLst
:
public
Option
{
public:
typedef
std
::
vector
<
isc
::
asiolink
::
IOAddress
>
AddrsContainer
;
/// @brief Constructor used during option generation.
///
/// @param type option type
/// @param addrs vector of addresses to be stored
///
Option6AddrLst
(
unsigned
short
type
,
AddrsContainer
&
addrs
);
/// @brief Simplified constructor for a single address
///
/// @param type option type
/// @param addr a single address to be stored
///
Option6AddrLst
(
unsigned
short
type
,
isc
::
asiolink
::
IOAddress
addr
);
/// @brief Constructor used for parsing received option
///
/// @param type option type
/// @param buf pointer to packet buffer
/// @param buf_len length of packet buffer
/// @param offset offset to beginning of option data
/// @param len length of option data
///
Option6AddrLst
(
unsigned
short
type
,
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
,
unsigned
int
len
);
/// @brief Assembles on-wire form of this option
///
/// @param buf pointer to packet buffer
/// @param buf_len length of packet buffer
/// @param offset offset to place, where option is to be stored
///
/// @return offset to the next unused char (just after stored option)
///
unsigned
int
pack
(
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
);
/// @brief Parses received data
///
/// @param buf pointer to packet buffer
/// @param buf_len length of packet buffer
/// @param offset offset to option data
/// @param parse_len specified option data length
///
/// @return offset to the next unparsed char (just after parsed option)
///
virtual
unsigned
int
unpack
(
boost
::
shared_array
<
char
>
buf
,
unsigned
int
buf_len
,
unsigned
int
offset
,
unsigned
int
parse_len
);
virtual
std
::
string
toText
(
int
indent
=
0
);
/// @brief Sets a single address.
///
/// @param addr a single address to be added
///
void
setAddress
(
isc
::
asiolink
::
IOAddress
addr
);
/// @brief Sets list of addresses.
///
/// @param addrs a vector of addresses to be added
///
void
setAddresses
(
std
::
vector
<
isc
::
asiolink
::
IOAddress
>&
addrs
);
/// @brief Returns vector with addresses.
///
/// As user may want to use/modify this list, it is better to return
/// a copy rather than const reference to the original. This is
/// usually one or two addresses long, so it is not a big deal.
///
/// @return vector with addresses
///
AddrsContainer
getAddresses
()
{
return
addrs_
;
};
// returns data length (data length + DHCPv4/DHCPv6 option header)
virtual
unsigned
short
len
();
protected:
AddrsContainer
addrs_
;
};
}
// isc::dhcp namespace
}
// isc namespace
#endif
/* OPTION_ADDRLST_H_ */
src/lib/dhcp/tests/Makefile.am
View file @
522d27a6
...
...
@@ -19,6 +19,7 @@ libdhcp_unittests_SOURCES = run_unittests.cc
libdhcp_unittests_SOURCES
+=
../libdhcp.h ../libdhcp.cc libdhcp_unittest.cc
libdhcp_unittests_SOURCES
+=
../option6_iaaddr.h ../option6_iaaddr.cc option6_iaaddr_unittest.cc
libdhcp_unittests_SOURCES
+=
../option6_ia.h ../option6_ia.cc option6_ia_unittest.cc
libdhcp_unittests_SOURCES
+=
../option6_addrlst.h ../option6_addrlst.cc option6_addrlst_unittest.cc
libdhcp_unittests_SOURCES
+=
../option.h ../option.cc option_unittest.cc
libdhcp_unittests_SOURCES
+=
../pkt6.h ../pkt6.cc pkt6_unittest.cc
...
...
src/lib/dhcp/tests/option6_addrlst_unittest.cc
0 → 100644
View file @
522d27a6
// Copyright (C) 2011 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
<config.h>
#include
<iostream>
#include
<sstream>
#include
<arpa/inet.h>
#include
<gtest/gtest.h>
#include
"io_address.h"
#include
"dhcp/dhcp6.h"
#include
"dhcp/option.h"
#include
"dhcp/option6_addrlst.h"
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
dhcp
;
using
namespace
isc
::
asiolink
;
namespace
{
class
Option6AddrLstTest
:
public
::
testing
::
Test
{
public:
Option6AddrLstTest
()
{
}
};
TEST_F
(
Option6AddrLstTest
,
basic
)
{
char
sampledata
[]
=
{
// 2001:db8:1::dead:beef
0x20
,
0x01
,
0x0d
,
0xb8
,
0x00
,
0x01
,
0
,
0
,
0
,
0
,
0
,
0
,
0xde
,
0xad
,
0xbe
,
0xef
,
// ff02::face:b00c
0xff
,
02
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0xfa
,
0xce
,
0xb0
,
0x0c
,
// ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
char
expected1
[]
=
{
D6O_NAME_SERVERS
/
256
,
D6O_NAME_SERVERS
%
256
,
//type
0
,
16
,
// len = 16 (1 address)
0x20
,
0x01
,
0x0d
,
0xb8
,
0x00
,
0x01
,
0
,
0
,
0
,
0
,
0
,
0
,
0xde
,
0xad
,
0xbe
,
0xef
,
};
char
expected2
[]
=
{
D6O_SIP_SERVERS_ADDR
/
256
,
D6O_SIP_SERVERS_ADDR
%
256
,
0
,
32
,
// len = 32 (2 addresses)
// 2001:db8:1::dead:beef
0x20
,
0x01
,
0x0d
,
0xb8
,
0x00
,
0x01
,
0
,
0
,
0
,
0
,
0
,
0
,
0xde
,
0xad
,
0xbe
,
0xef
,
// ff02::face:b00c
0xff
,
02
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0xfa
,
0xce
,
0xb0
,
0x0c
,
// ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
char
expected3
[]
=
{
D6O_NIS_SERVERS
/
256
,
D6O_NIS_SERVERS
%
256
,
0
,
48
,
// 2001:db8:1::dead:beef
0x20
,
0x01
,
0x0d
,
0xb8
,
0x00
,
0x01
,
0
,
0
,
0
,
0
,
0
,
0
,
0xde
,
0xad
,
0xbe
,
0xef
,
// ff02::face:b00c
0xff
,
02
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0xfa
,
0xce
,
0xb0
,
0x0c
,
// ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
,
0xff
};
boost
::
shared_array
<
char
>
buf
(
new
char
[
300
]);
for
(
int
i
=
0
;
i
<
300
;
i
++
)
buf
[
i
]
=
0
;
memcpy
(
&
buf
[
0
],
sampledata
,
48
);
// just a single address
Option6AddrLst
*
opt1
=
new
Option6AddrLst
(
D6O_NAME_SERVERS
,
buf
,
128
,
0
,
16
);
EXPECT_EQ
(
D6O_NAME_SERVERS
,
opt1
->
getType
());
EXPECT_EQ
(
20
,
opt1
->
len
());
Option6AddrLst
::
AddrsContainer
addrs
=
opt1
->
getAddresses
();
ASSERT_EQ
(
1
,
addrs
.
size
());
IOAddress
addr
=
addrs
[
0
];
EXPECT_EQ
(
"2001:db8:1::dead:beef"
,
addr
.
toText
());
// pack this option again in the same buffer, but in
// different place
int
offset
=
opt1
->
pack
(
buf
,
300
,
100
);
EXPECT_EQ
(
120
,
offset
);
EXPECT_EQ
(
0
,
memcmp
(
expected1
,
&
buf
[
100
],
20
)
);
// two addresses
Option6AddrLst
*
opt2
=
new
Option6AddrLst
(
D6O_SIP_SERVERS_ADDR
,
buf
,
128
,
0
,
32
);
EXPECT_EQ
(
D6O_SIP_SERVERS_ADDR
,
opt2
->
getType
());
EXPECT_EQ
(
36
,
opt2
->
len
());
addrs
=
opt2
->
getAddresses
();
ASSERT_EQ
(
2
,
addrs
.
size
());
EXPECT_EQ
(
"2001:db8:1::dead:beef"
,
addrs
[
0
].
toText
());
EXPECT_EQ
(
"ff02::face:b00c"
,
addrs
[
1
].
toText
());
// pack this option again in the same buffer, but in
// different place
offset
=
opt2
->
pack
(
buf
,
300
,
150
);
EXPECT_EQ
(
150
+
36
,
offset
);
EXPECT_EQ
(
0
,
memcmp
(
expected2
,
&
buf
[
150
],
36
));
// three addresses
Option6AddrLst
*
opt3
=
new
Option6AddrLst
(
D6O_NIS_SERVERS
,
buf
,
128
,
0
,
48
);
EXPECT_EQ
(
D6O_NIS_SERVERS
,
opt3
->
getType
());
EXPECT_EQ
(
52
,
opt3
->
len
());
addrs
=
opt3
->
getAddresses
();
ASSERT_EQ
(
3
,
addrs
.
size
());
EXPECT_EQ
(
"2001:db8:1::dead:beef"
,
addrs
[
0
].
toText
());
EXPECT_EQ
(
"ff02::face:b00c"
,
addrs
[
1
].
toText
());
EXPECT_EQ
(
"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
,
addrs
[
2
].
toText
());
// pack this option again in the same buffer, but in
// different place
offset
=
opt3
->
pack
(
buf
,
300
,
200
);
EXPECT_EQ
(
252
,
offset
);
EXPECT_EQ
(
0
,
memcmp
(
expected3
,
&
buf
[
200
],
52
)
);
delete
opt1
;
delete
opt2
;
delete
opt3
;
}
TEST_F
(
Option6AddrLstTest
,
constructors
)
{
Option6AddrLst
*
opt1
=
new
Option6AddrLst
(
1234
,
IOAddress
(
"::1"
));
EXPECT_EQ
(
1234
,
opt1
->
getType
());
Option6AddrLst
::
AddrsContainer
addrs
=
opt1
->
getAddresses
();
ASSERT_EQ
(
1
,
addrs
.
size
()
);
EXPECT_EQ
(
"::1"
,
addrs
[
0
].
toText
());
addrs
.
clear
();
addrs
.
push_back
(
IOAddress
(
string
(
"fe80::1234"
)));
addrs
.
push_back
(
IOAddress
(
string
(
"2001:db8:1::baca"
)));
Option6AddrLst
*
opt2
=
new
Option6AddrLst
(
5678
,
addrs
);
Option6AddrLst
::
AddrsContainer
check
=
opt2
->
getAddresses
();
ASSERT_EQ
(
2
,
check
.
size
()
);
EXPECT_EQ
(
"fe80::1234"
,
check
[
0
].
toText
());
EXPECT_EQ
(
"2001:db8:1::baca"
,
check
[
1
].
toText
());
delete
opt1
;
delete
opt2
;
}
TEST_F
(
Option6AddrLstTest
,
setAddress
)
{
Option6AddrLst
*
opt1
=
new
Option6AddrLst
(
1234
,
IOAddress
(
"::1"
));
opt1
->
setAddress
(
IOAddress
(
"::2"
));
Option6AddrLst
::
AddrsContainer
addrs
=
opt1
->
getAddresses
();
ASSERT_EQ
(
1
,
addrs
.
size
()
);
EXPECT_EQ
(
"::2"
,
addrs
[
0
].
toText
());
delete
opt1
;
}
}
// namespace
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment