Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
Adam Osuchowski
Kea
Commits
e3ada096
Commit
e3ada096
authored
Jul 15, 2014
by
Marcin Siodelski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[3390] Implemented DHCPINFORM message processing by the server.
parent
852fb7c1
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
80 additions
and
12 deletions
+80
-12
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/dhcp4_srv.cc
+77
-10
src/bin/dhcp4/dhcp4_srv.h
src/bin/dhcp4/dhcp4_srv.h
+3
-2
No files found.
src/bin/dhcp4/dhcp4_srv.cc
View file @
e3ada096
...
...
@@ -299,7 +299,7 @@ Dhcpv4Srv::run() {
break
;
case
DHCPINFORM
:
processInform
(
query
);
rsp
=
processInform
(
query
);
break
;
default:
...
...
@@ -1133,8 +1133,41 @@ Dhcpv4Srv::adjustRemoteAddr(const Pkt4Ptr& question, const Pkt4Ptr& response) {
static
const
IOAddress
zero_addr
(
"0.0.0.0"
);
static
const
IOAddress
bcast_addr
(
"255.255.255.255"
);
// The DHCPINFORM is slightly different than other messages in a sense
// that the server should always unicast the response to the ciaddr.
// It appears however that some clients don't set the ciaddr. We still
// want to provision these clients and we do what we can't to send the
// packet to the address where client can receive it.
if
(
question
->
getType
()
==
DHCPINFORM
)
{
// If client adheres to RFC2131 it will set the ciaddr and in this
// case we always unicast our response to this address.
if
(
question
->
getCiaddr
()
!=
zero_addr
)
{
response
->
setRemoteAddr
(
question
->
getCiaddr
());
// If we received DHCPINFOM via relay and the ciaddr is not set we
// will try to send the response via relay. The caveat is that the
// relay will not have any idea where to forward the packet because
// the yiaddr is likely not set. So, the broadcast flag is set so
// as the response may be broadcast.
}
else
if
(
question
->
isRelayed
())
{
response
->
setRemoteAddr
(
question
->
getGiaddr
());
response
->
setFlags
(
response
->
getFlags
()
|
BOOTP_BROADCAST
);
// If there is no ciaddr and no giaddr the only thing we can do is
// to use the source address of the packet.
}
else
{
response
->
setRemoteAddr
(
question
->
getRemoteAddr
());
}
// Remote addres is now set so return.
return
;
}
// If received relayed message, server responds to the relay address.
if
(
question
->
isRelayed
())
{
if
((
question
->
getType
()
==
DHCPINFORM
)
&&
(
question
->
getCiaddr
()
==
zero_addr
))
{
response
->
setFlags
(
BOOTP_BROADCAST
);
}
response
->
setRemoteAddr
(
question
->
getGiaddr
());
// If giaddr is 0 but client set ciaddr, server should unicast the
...
...
@@ -1385,9 +1418,26 @@ Dhcpv4Srv::processDecline(Pkt4Ptr& /* decline */) {
Pkt4Ptr
Dhcpv4Srv
::
processInform
(
Pkt4Ptr
&
inform
)
{
/// @todo Implement this for real. (also see ticket #3116)
return
(
inform
);
Pkt4Ptr
ack
=
Pkt4Ptr
(
new
Pkt4
(
DHCPACK
,
inform
->
getTransid
()));
copyDefaultFields
(
inform
,
ack
);
appendRequestedOptions
(
inform
,
ack
);
appendRequestedVendorOptions
(
inform
,
ack
);
adjustIfaceData
(
inform
,
ack
);
// There are cases for the DHCPINFORM that the server receives it via
// relay but will send the response to the client's unicast address
// carried in the ciaddr. In this case, the giaddr and hops field should
// be cleared (these fields were copied by the copyDefaultFields function).
// Also Relay Agent Options should be removed if present.
if
(
ack
->
getRemoteAddr
()
!=
inform
->
getGiaddr
())
{
ack
->
setHops
(
0
);
ack
->
setGiaddr
(
IOAddress
(
"0.0.0.0"
));
ack
->
delOption
(
DHO_DHCP_AGENT_OPTIONS
);
}
// The DHCPACK must contain server id.
appendServerID
(
ack
);
return
(
ack
);
}
const
char
*
...
...
@@ -1493,6 +1543,12 @@ Dhcpv4Srv::selectSubnet(const Pkt4Ptr& question) const {
bool
Dhcpv4Srv
::
accept
(
const
Pkt4Ptr
&
query
)
const
{
// Check that the message type is accepted by the server. We rely on the
// function called to log a message if needed.
if
(
!
acceptMessageType
(
query
))
{
return
(
false
);
}
// Check if the message from directly connected client (if directly
// connected) should be dropped or processed.
if
(
!
acceptDirectRequest
(
query
))
{
...
...
@@ -1511,12 +1567,6 @@ Dhcpv4Srv::accept(const Pkt4Ptr& query) const {
return
(
false
);
}
// Check that the message type is accepted by the server. We rely on the
// function called to log a message if needed.
if
(
!
acceptMessageType
(
query
))
{
return
(
false
);
}
return
(
true
);
}
...
...
@@ -1529,6 +1579,23 @@ Dhcpv4Srv::acceptDirectRequest(const Pkt4Ptr& pkt) const {
}
catch
(
const
Exception
&
ex
)
{
return
(
false
);
}
// The source address must not be zero for the DHCPINFORM message from
// the directly connected client because the server will not know where
// to respond if the ciaddr was not present.
static
const
IOAddress
zero_addr
(
"0.0.0.0"
);
try
{
if
(
pkt
->
getType
()
==
DHCPINFORM
)
{
if
((
pkt
->
getRemoteAddr
()
==
zero_addr
)
&&
(
pkt
->
getCiaddr
()
==
zero_addr
))
{
return
(
false
);
}
}
}
catch
(...)
{
// If we got here, it is probably because the message type hasn't
// been set. But, this should not really happen assuming that
// we validate the message type prior to calling this function.
return
(
false
);
}
static
const
IOAddress
bcast
(
"255.255.255.255"
);
return
((
pkt
->
getLocalAddr
()
!=
bcast
||
selectSubnet
(
pkt
)));
}
...
...
src/bin/dhcp4/dhcp4_srv.h
View file @
e3ada096
...
...
@@ -239,8 +239,9 @@ protected:
/// This function accepts the following messages:
/// - all valid relayed messages,
/// - all unicast messages,
/// - all broadcast messages received on the interface for which the
/// suitable subnet exists (is configured).
/// - all broadcast messages except DHCPINFORM received on the interface
/// for which the suitable subnet exists (is configured).
/// - all DHCPINFORM messages with source address or ciaddr set.
///
/// @param query Message sent by a client.
///
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a 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