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
Sebastian Schrader
Kea
Commits
b0c84e76
Commit
b0c84e76
authored
Oct 18, 2013
by
Tomek Mrugalski
🛰
Browse files
[3203] Client classification added in DHCPv4.
parent
8840cfe8
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/bin/dhcp4/dhcp4_messages.mes
View file @
b0c84e76
...
...
@@ -32,6 +32,14 @@ This debug message is issued when the DHCP server was unable to process the
FQDN or Hostname option sent by a client. This is likely because the client's
name was malformed or due to internal server error.
% DHCP4_CLASS_PROCESSING_FAILED client class specific processing failed
This debug message means that the server processing that is unique for each
client class has reported a failure. The response packet will not be sent.
% DHCP4_CLASS_ASSIGNED client packet has been assigned to the following class(es): %1
This debug message informs that incoming packet has been assigned to specified
class or classes. This is a norma
% DHCP4_COMMAND_RECEIVED received command %1, arguments: %2
A debug message listing the command (and possible arguments) received
from the BIND 10 control system by the IPv4 DHCP server.
...
...
src/bin/dhcp4/dhcp4_srv.cc
View file @
b0c84e76
...
...
@@ -21,6 +21,7 @@
#include
<dhcp/option_int.h>
#include
<dhcp/option_int_array.h>
#include
<dhcp/option_vendor.h>
#include
<dhcp/option_string.h>
#include
<dhcp/pkt4.h>
#include
<dhcp/docsis3_option_defs.h>
#include
<dhcp4/dhcp4_log.h>
...
...
@@ -333,6 +334,9 @@ Dhcpv4Srv::run() {
callout_handle
->
getArgument
(
"query4"
,
query
);
}
// Assign this packet to one or more classes if needed
classifyPacket
(
query
);
try
{
switch
(
query
->
getType
())
{
case
DHCPDISCOVER
:
...
...
@@ -391,7 +395,14 @@ Dhcpv4Srv::run() {
adjustRemoteAddr
(
query
,
rsp
);
if
(
!
rsp
->
getHops
())
{
if
(
!
classSpecificProcessing
(
query
,
rsp
))
{
/// @todo add more verbosity here
LOG_DEBUG
(
dhcp4_logger
,
DBG_DHCP4_BASIC
,
DHCP4_CLASS_PROCESSING_FAILED
);
continue
;
}
if
(
query
->
getRemotePort
()
==
DHCP4_CLIENT_PORT
)
{
rsp
->
setRemotePort
(
DHCP4_CLIENT_PORT
);
}
else
{
rsp
->
setRemotePort
(
DHCP4_SERVER_PORT
);
...
...
@@ -1783,5 +1794,69 @@ Dhcpv4Srv::ifaceMgrSocket4ErrorHandler(const std::string& errmsg) {
LOG_WARN
(
dhcp4_logger
,
DHCP4_OPEN_SOCKET_FAIL
).
arg
(
errmsg
);
}
void
Dhcpv4Srv
::
classifyPacket
(
const
Pkt4Ptr
&
pkt
)
{
boost
::
shared_ptr
<
OptionString
>
vendor_class
=
boost
::
dynamic_pointer_cast
<
OptionString
>
(
pkt
->
getOption
(
DHO_VENDOR_CLASS_IDENTIFIER
));
string
classes
=
""
;
if
(
!
vendor_class
)
{
return
;
}
// DOCSIS specific section
if
(
vendor_class
->
getValue
().
find
(
"docsis3.0"
)
!=
std
::
string
::
npos
)
{
pkt
->
addClass
(
"docsis3.0"
);
classes
+=
"docsis3.0 "
;
}
if
(
vendor_class
->
getValue
().
find
(
"eRouter1.0"
)
!=
std
::
string
::
npos
)
{
pkt
->
addClass
(
"eRouter1.0"
);
classes
+=
"eRouter1.0 "
;
}
classes
+=
vendor_class
->
getValue
();
pkt
->
addClass
(
vendor_class
->
getValue
());
if
(
!
classes
.
empty
())
{
LOG_DEBUG
(
dhcp4_logger
,
DBG_DHCP4_BASIC
,
DHCP4_CLASS_ASSIGNED
)
.
arg
(
classes
);
}
}
bool
Dhcpv4Srv
::
classSpecificProcessing
(
const
Pkt4Ptr
&
query
,
const
Pkt4Ptr
&
rsp
)
{
Subnet4Ptr
subnet
=
selectSubnet
(
query
);
if
(
!
subnet
)
{
return
(
true
);
}
if
(
query
->
inClass
(
"docsis3.0"
))
{
// set next-server
// @todo uncomment this once 3191 is merged
// rsp->setSiaddr(subnet->getSiaddr());
Subnet
::
OptionDescriptor
desc
=
subnet
->
getOptionDescriptor
(
"dhcp4"
,
DHO_BOOT_FILE_NAME
);
if
(
desc
.
option
)
{
boost
::
shared_ptr
<
OptionString
>
boot
=
boost
::
dynamic_pointer_cast
<
OptionString
>
(
desc
.
option
);
if
(
boot
)
{
std
::
string
filename
=
boot
->
getValue
();
rsp
->
setFile
((
const
uint8_t
*
)
filename
.
c_str
(),
filename
.
size
());
}
}
}
if
(
query
->
inClass
(
"eRouter1.0"
))
{
}
return
(
true
);
}
}
// namespace dhcp
}
// namespace isc
src/bin/dhcp4/dhcp4_srv.h
View file @
b0c84e76
...
...
@@ -517,6 +517,19 @@ protected:
const
std
::
string
&
option_space
,
isc
::
dhcp
::
OptionCollection
&
options
);
/// @brief Assigns incoming packet to a given class
/// @param pkt packet to be classified
void
classifyPacket
(
const
Pkt4Ptr
&
pkt
);
/// @brief Performs packet processing specific to a class
///
/// This processing is a likely candidate to be pushed into hooks.
///
/// @param query incoming client's packet
/// @param rsp server's response
/// @return true if successful, false otherwise (will prevent sending response)
bool
classSpecificProcessing
(
const
Pkt4Ptr
&
query
,
const
Pkt4Ptr
&
rsp
);
private:
/// @brief Constructs netmask option based on subnet4
...
...
src/bin/dhcp4/tests/dhcp4_srv_unittest.cc
View file @
b0c84e76
...
...
@@ -2995,8 +2995,32 @@ TEST_F(Dhcpv4SrvTest, vendorOptionsDocsisDefinitions) {
ASSERT_EQ
(
0
,
rcode_
);
}
// Checks if client packets are classified properly
TEST_F
(
Dhcpv4SrvTest
,
clientClassification
)
{
NakedDhcpv4Srv
srv
(
0
);
// Let's create a relayed DISCOVER. This particular relayed DISCOVER has
// vendor-class set to docsis3.0
Pkt4Ptr
dis1
;
ASSERT_NO_THROW
(
dis1
=
captureRelayedDiscover
());
ASSERT_NO_THROW
(
dis1
->
unpack
());
srv
.
classifyPacket
(
dis1
);
EXPECT_TRUE
(
dis1
->
inClass
(
"docsis3.0"
));
EXPECT_FALSE
(
dis1
->
inClass
(
"eRouter1.0"
));
// Let's create a relayed DISCOVER. This particular relayed DISCOVER has
// vendor-class set to eRouter1.0
Pkt4Ptr
dis2
;
ASSERT_NO_THROW
(
dis2
=
captureRelayedDiscover2
());
ASSERT_NO_THROW
(
dis2
->
unpack
());
srv
.
classifyPacket
(
dis2
);
EXPECT_TRUE
(
dis2
->
inClass
(
"eRouter1.0"
));
EXPECT_FALSE
(
dis2
->
inClass
(
"docsis3.0"
));
}
/*I}; // end of isc::dhcp::test namespace
}; // end of isc::dhcp namespace
}; // end of isc namespace */
};
// end of anonymous namespace
src/bin/dhcp4/tests/dhcp4_test_utils.h
View file @
b0c84e76
...
...
@@ -206,7 +206,8 @@ public:
/// @brief returns captured DISCOVER that went through a relay
///
/// See method code for a detailed explanation.
/// See method code for a detailed explanation. This is a discover from
/// docsis3.0 device (Cable Modem)
///
/// @return relayed DISCOVER
Pkt4Ptr
captureRelayedDiscover
();
...
...
@@ -237,6 +238,14 @@ public:
createPacketFromBuffer
(
const
Pkt4Ptr
&
src_pkt
,
Pkt4Ptr
&
dst_pkt
);
/// @brief returns captured DISCOVER that went through a relay
///
/// See method code for a detailed explanation. This is a discover from
/// eRouter1.0 device (CPE device integrated with cable modem)
///
/// @return relayed DISCOVER
Pkt4Ptr
captureRelayedDiscover2
();
/// @brief generates a DHCPv4 packet based on provided hex string
///
/// @return created packet
...
...
@@ -374,6 +383,7 @@ public:
using
Dhcpv4Srv
::
srvidToString
;
using
Dhcpv4Srv
::
unpackOptions
;
using
Dhcpv4Srv
::
name_change_reqs_
;
using
Dhcpv4Srv
::
classifyPacket
;
};
};
// end of isc::dhcp::test namespace
...
...
src/bin/dhcp4/tests/wireshark.cc
View file @
b0c84e76
...
...
@@ -71,7 +71,10 @@ void Dhcpv4SrvTest::captureSetDefaultFields(const Pkt4Ptr& pkt) {
Pkt4Ptr
Dhcpv4SrvTest
::
captureRelayedDiscover
()
{
/* string exported from Wireshark:
/* This is packet 1 from capture
dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
string exported from Wireshark:
User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67)
Source port: bootps (67)
...
...
@@ -98,7 +101,7 @@ Bootstrap Protocol
Magic cookie: DHCP
Option: (53) DHCP Message Type
Option: (55) Parameter Request List
Option: (60) Vendor class identifier
Option: (60) Vendor class identifier
(docsis3.0)
Option: (125) V-I Vendor-specific Information
- suboption 1 (Option Request): requesting option 2
- suboption 5 (Modem Caps): 117 bytes
...
...
@@ -129,6 +132,59 @@ Bootstrap Protocol
return
(
packetFromCapture
(
hex_string
));
}
Pkt4Ptr
Dhcpv4SrvTest
::
captureRelayedDiscover2
()
{
/* This is packet 5 from capture
dhcp-val/pcap/docsis-*-CG3000DCR-Registration-Filtered.cap
string exported from Wireshark:
User Datagram Protocol, Src Port: bootps (67), Dst Port: bootps (67)
Bootstrap Protocol
Message type: Boot Request (1)
Hardware type: Ethernet (0x01)
Hardware address length: 6
Hops: 1
Transaction ID: 0x5d05478f
Seconds elapsed: 5
Bootp flags: 0x0000 (Unicast)
Client IP address: 0.0.0.0 (0.0.0.0)
Your (client) IP address: 0.0.0.0 (0.0.0.0)
Next server IP address: 0.0.0.0 (0.0.0.0)
Relay agent IP address: 10.254.226.1 (10.254.226.1)
Client MAC address: Netgear_b8:15:15 (20:e5:2a:b8:15:15)
Client hardware address padding: 00000000000000000000
Server host name not given
Boot file name not given
Magic cookie: DHCP
Option: (53) DHCP Message Type
Option: (55) Parameter Request List
Option: (43) Vendor-Specific Information
Option: (60) Vendor class identifier (eRouter1.0)
Option: (15) Domain Name
Option: (61) Client identifier
Option: (57) Maximum DHCP Message Size
Option: (82) Agent Information Option
Option: (255) End */
string
hex_string
=
"010106015d05478f000500000000000000000000000000000afee20120e52ab8151500"
"0000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000000000000000"
"000000000000000000000000000000000000000000000000000063825363350101370e"
"480102030406070c0f171a36337a2b63020745524f55544552030b45434d3a45524f55"
"544552040d324252323239553430303434430504312e3034060856312e33332e303307"
"07322e332e305232080630303039354209094347333030304443520a074e6574676561"
"720f0745524f555445523c0a65526f75746572312e300f14687364312e70612e636f6d"
"636173742e6e65742e3d0fff2ab815150003000120e52ab81515390205dc5219010420"
"000002020620e52ab8151409090000118b0401020300ff"
;
return
(
packetFromCapture
(
hex_string
));
}
};
// end of isc::dhcp::test namespace
};
// end of isc::dhcp namespace
};
// end of isc 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