Skip to content

Commit 2fe49af

Browse files
authored
Merge pull request #257 from rdkcentral/development/BCM72180-9
NetworkControl: Changes to set src address as 0.0.0.0 for DHCP requests
2 parents 31e73d0 + 3f56a4c commit 2fe49af

File tree

4 files changed

+82
-40
lines changed

4 files changed

+82
-40
lines changed

NetworkControl/DHCPClient.cpp

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,30 @@ namespace Plugin {
2626
/* static */ constexpr uint8_t DHCPClient::MagicCookie[];
2727
static Core::NodeId BroadcastClientNode (_T("0.0.0.0"), DHCPClient::DefaultDHCPClientPort, Core::NodeId::TYPE_IPV4);
2828
static Core::NodeId BroadcastServerNode (_T("255.255.255.255"), DHCPClient::DefaultDHCPServerPort, Core::NodeId::TYPE_IPV4);
29+
static const uint8_t BroadcastMAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
2930

3031
DHCPClient::DHCPClient(const string& interfaceName, ICallback* callback)
31-
: Core::SocketDatagram(false, BroadcastClientNode, BroadcastServerNode, 512, 1024)
32+
: Core::SocketDatagram(
33+
false,
34+
#ifdef __WINDOWS__
35+
BroadcastClientNode,
36+
BroadcastServerNode,
37+
#else
38+
Core::NodeId(interfaceName.c_str(), ETH_P_IP, PACKET_BROADCAST, 0, sizeof(BroadcastMAC), BroadcastMAC),
39+
Core::NodeId(interfaceName.c_str(), ETH_P_IP, PACKET_BROADCAST, 0, sizeof(BroadcastMAC), BroadcastMAC),
40+
#endif
41+
512,
42+
1024)
3243
, _adminLock()
3344
, _interfaceName(interfaceName)
3445
, _state(IDLE)
3546
, _modus(CLASSIFICATION_INVALID)
3647
, _serverIdentifier(0)
3748
, _xid(0)
3849
, _offer()
50+
, _udpFrame(BroadcastClientNode, BroadcastServerNode)
3951
, _callback(callback)
4052
{
41-
Core::AdapterIterator adapters(_interfaceName);
42-
43-
if (adapters.IsValid() == true) {
44-
adapters.MACAddress(_MAC, sizeof(_MAC));
45-
} else {
46-
TRACE_L1("Could not read mac address of %s\n", _interfaceName.c_str());
47-
}
4853
}
4954

5055
/* virtual */ DHCPClient::~DHCPClient()
@@ -53,26 +58,58 @@ namespace Plugin {
5358
}
5459

5560
// Methods to extract and insert data into the socket buffers
56-
/* virtual */ uint16_t DHCPClient::SendData(uint8_t* dataFrame, const uint16_t maxSendSize)
61+
uint16_t DHCPClient::SendData(uint8_t* dataFrame, const uint16_t maxSendSize) /* override */
5762
{
5863
uint16_t result = 0;
5964

65+
_adminLock.Lock();
66+
6067
if (_state == SENDING) {
6168
_state = RECEIVING;
6269

63-
RemoteNode(BroadcastServerNode);
70+
TRACE_L1 ("Sending for mode :%d", _modus);
6471

65-
TRACE_L1("Sending DHCP message type: %d for interface: %s", _modus, _interfaceName.c_str());
72+
#ifdef __WINDOWS__
6673
result = Message(dataFrame, maxSendSize);
74+
#else
75+
result = Message(_udpFrame.Frame(), _udpFrame.FrameSize);
76+
77+
if (result > 0) {
78+
_udpFrame.Length(result);
79+
80+
// We are not running on a RAW socket but on an IP_PACKET socket, so we need to do all from
81+
// the IP layer up. The kernel will add the Ethernet part...
82+
result = std::min(maxSendSize, static_cast<uint16_t>(_udpFrame.Size() - Core::EthernetFrameSize));
83+
84+
::memcpy(dataFrame, &(_udpFrame.Data()[Core::EthernetFrameSize]), result);
85+
}
86+
#endif
6787
}
6888

89+
_adminLock.Unlock();
90+
6991
return (result);
7092
}
7193

72-
/* virtual */ uint16_t DHCPClient::ReceiveData(uint8_t* dataFrame, const uint16_t receivedSize)
94+
uint16_t DHCPClient::ReceiveData(uint8_t* dataFrame, const uint16_t receivedSize) /* override */
7395
{
74-
ProcessMessage(SocketDatagram::ReceivedNode(), dataFrame, receivedSize);
96+
#ifdef __WINDOWS__
97+
ProcessMessage(ReceivedNode(), dataFrame, receivedSize);
98+
#else
99+
UDPv4Frame udpFrame;
100+
101+
// The load should take place at the IPFrame level, so at the base of the UDP4Frame...
102+
uint16_t result = static_cast<UDPv4Frame::Base&>(udpFrame).Load(dataFrame, receivedSize);
75103

104+
// Make sure the package fits...
105+
ASSERT(result == receivedSize);
106+
107+
if ((udpFrame.IsValid() == true) &&
108+
(udpFrame.SourcePort() == DHCPClient::DefaultDHCPServerPort) &&
109+
(udpFrame.DestinationPort() == DHCPClient::DefaultDHCPClientPort)) {
110+
ProcessMessage(udpFrame.Source(), udpFrame.Frame(), udpFrame.Length());
111+
}
112+
#endif
76113
return (receivedSize);
77114
}
78115

NetworkControl/DHCPClient.h

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ namespace Plugin {
4040
};
4141

4242
private:
43+
using UDPv4Frame = Core::UDPv4FrameType<1024>;
44+
4345
enum state : uint8_t {
4446
IDLE,
4547
SENDING,
@@ -106,6 +108,7 @@ namespace Plugin {
106108
};
107109
#pragma pack(pop)
108110

111+
109112
public:
110113
// DHCP constants (see RFC 2131 section 4.1)
111114
static constexpr uint16_t DefaultDHCPServerPort = 67;
@@ -493,10 +496,9 @@ namespace Plugin {
493496
const string& Interface() const {
494497
return (_interfaceName);
495498
}
496-
inline void UpdateMAC(const uint8_t buffer[], const uint8_t size) {
497-
ASSERT(size == sizeof(_MAC));
498-
499-
memcpy(_MAC, buffer, sizeof(_MAC));
499+
void UpdateMAC(const uint8_t buffer[], const uint8_t size) {
500+
ASSERT(size == _udpFrame.MACSize);
501+
_udpFrame.SourceMAC(buffer);
500502
}
501503
/* Ask DHCP servers for offers. */
502504
inline uint32_t Discover(const Core::NodeId& preferredAddres)
@@ -523,7 +525,7 @@ namespace Plugin {
523525
result = Core::ERROR_NONE;
524526

525527
Core::SocketDatagram::Broadcast(true);
526-
SocketDatagram::Trigger();
528+
Core::SocketDatagram::Trigger();
527529

528530
} else {
529531
_adminLock.Unlock();
@@ -560,7 +562,7 @@ namespace Plugin {
560562
memcpy(&_serverIdentifier, &(addr->sin_addr), 4);
561563

562564
Core::SocketDatagram::Broadcast(true);
563-
SocketDatagram::Trigger();
565+
Core::SocketDatagram::Trigger();
564566
}
565567
else {
566568
_adminLock.Unlock();
@@ -594,8 +596,7 @@ namespace Plugin {
594596
_modus = CLASSIFICATION_RELEASE;
595597

596598
result = Core::ERROR_NONE;
597-
Core::SocketDatagram::Broadcast(true);
598-
SocketDatagram::Trigger();
599+
Core::SocketDatagram::Trigger();
599600
}
600601
else {
601602
_adminLock.Unlock();
@@ -638,6 +639,7 @@ namespace Plugin {
638639

639640
uint16_t Message(uint8_t stream[], const uint16_t length) const
640641
{
642+
641643
CoreMessage& frame(*reinterpret_cast<CoreMessage*>(stream));
642644

643645
/* clear the packet data structure */
@@ -650,7 +652,7 @@ namespace Plugin {
650652
frame.htype = 1; // ETHERNET_HARDWARE_ADDRESS
651653

652654
/* length of our hardware address */
653-
frame.hlen = static_cast<uint8_t>(sizeof(_MAC)); // ETHERNET_HARDWARE_ADDRESS_LENGTH;
655+
frame.hlen = _udpFrame.MACSize; // ETHERNET_HARDWARE_ADDRESS_LENGTH;
654656

655657
frame.hops = 0;
656658

@@ -664,7 +666,7 @@ namespace Plugin {
664666
frame.flags = htons(BroadcastValue);
665667

666668
/* our hardware address */
667-
::memcpy(frame.chaddr, _MAC, frame.hlen);
669+
::memcpy(frame.chaddr, _udpFrame.SourceMAC(), frame.hlen);
668670

669671
/* Close down the header field with a magic cookie (as per RFC 2132) */
670672
::memcpy(frame.magicCookie, MagicCookie, sizeof(frame.magicCookie));
@@ -691,7 +693,7 @@ namespace Plugin {
691693
options[index++] = OPTION_CLIENTIDENTIFIER;
692694
options[index++] = frame.hlen + 1; // Identifier length
693695
options[index++] = 1; // Ethernet hardware
694-
::memcpy(&(options[index]), _MAC, frame.hlen);
696+
::memcpy(&(options[index]), _udpFrame.SourceMAC(), frame.hlen);
695697
index += frame.hlen;
696698

697699
/* Ask for extended informations in offer */
@@ -724,9 +726,9 @@ namespace Plugin {
724726
const CoreMessage& frame(*reinterpret_cast<const CoreMessage*>(stream));
725727
const uint32_t xid = ntohl(frame.xid);
726728

727-
if (::memcmp(frame.chaddr, _MAC, sizeof(_MAC)) != 0) {
729+
if (::memcmp(frame.chaddr, _udpFrame.SourceMAC(), _udpFrame.MACSize) != 0) {
728730
TRACE(Trace::Information, (_T("Unknown CHADDR encountered.")));
729-
} else if ((sizeof(_MAC) < sizeof(frame.chaddr)) && (IsZero(&(frame.chaddr[sizeof(_MAC)]), sizeof(frame.chaddr) - sizeof(_MAC)) == false)) {
731+
} else if ((_udpFrame.MACSize < sizeof(frame.chaddr)) && (IsZero(&(frame.chaddr[_udpFrame.MACSize]), sizeof(frame.chaddr) - _udpFrame.MACSize) == false)) {
730732
TRACE(Trace::Information, (_T("Unknown CHADDR (clearance) encountered.")));
731733
} else {
732734
const uint8_t* optionsRaw = reinterpret_cast<const uint8_t*>(&(stream[result]));
@@ -796,10 +798,10 @@ namespace Plugin {
796798
string _interfaceName;
797799
state _state;
798800
classifications _modus;
799-
uint8_t _MAC[6];
800801
uint32_t _serverIdentifier;
801802
uint32_t _xid;
802803
Offer _offer;
804+
UDPv4Frame _udpFrame;
803805
ICallback* _callback;
804806
Core::Time _expired;
805807
};

NetworkControl/NetworkControl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ namespace Plugin
3232

3333
static bool ExternallyAccessible(const Core::AdapterIterator& index) {
3434

35-
ASSERT (index.IsValid());
35+
ASSERT(index.IsValid());
3636

3737
bool accessible = index.IsRunning();
3838

@@ -509,7 +509,7 @@ namespace Plugin
509509
}
510510
}
511511

512-
ASSERT (count <= _requiredSet.size());
512+
ASSERT(count <= _requiredSet.size());
513513

514514
fullSet &= ( (count == _requiredSet.size()) && validIP );
515515

NetworkControl/NetworkControl.h

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ namespace Plugin {
461461
{
462462
Core::AdapterIterator hardware(_client.Interface());
463463

464-
if (hardware.IsValid() == false) {
464+
if ((hardware.IsValid() == false) || (hardware.IsRunning() == false)) {
465465
// If the interface is nolonger available, no need to reschedule , just report Failed!
466466
_client.Close();
467467
_parent.Failed(_client.Interface());
@@ -488,6 +488,7 @@ namespace Plugin {
488488
// We are good to go report success!, if this is a different set..
489489
if (_settings.Store(_client.Lease()) == true) {
490490
_parent.Accepted(_client.Interface(), _client.Lease());
491+
_client.Close();
491492
}
492493
_retries = 0;
493494
_job.Schedule(_client.Expired());
@@ -524,6 +525,8 @@ namespace Plugin {
524525
DHCPClient::Offer& node (_offers.front());
525526
hardware.Add(Core::IPNode(node.Address(), node.Netmask()));
526527

528+
TRACE(Trace::Information, ("Requesting a lease, for [%s]", node.Address().HostAddress().c_str()));
529+
527530
// Seems we have some offers pending and we are not Active yet, request an ACK
528531
_client.Request(node);
529532
_retries = 0;
@@ -544,17 +547,17 @@ namespace Plugin {
544547
{
545548
info.Mode = _settings.Mode();
546549
info.Interface = _client.Interface();
547-
if (_settings.Address().IsValid() == true) {
548-
info.Address = _settings.Address().HostAddress();
549-
info.Mask = _settings.Address().Mask();
550-
if (_settings.Gateway().IsValid() == true) {
551-
info.Gateway = _settings.Gateway().HostAddress();
552-
}
553-
if (_settings.Broadcast().IsValid() == true) {
554-
info.Broadcast(_settings.Broadcast());
555-
}
556-
}
557550
if (_client.HasActiveLease() == true) {
551+
if (_settings.Address().IsValid() == true) {
552+
info.Address = _settings.Address().HostAddress();
553+
info.Mask = _settings.Address().Mask();
554+
if (_settings.Gateway().IsValid() == true) {
555+
info.Gateway = _settings.Gateway().HostAddress();
556+
}
557+
if (_settings.Broadcast().IsValid() == true) {
558+
info.Broadcast(_settings.Broadcast());
559+
}
560+
}
558561
DHCPClient::Offer offer(_client.Lease());
559562
info.Source = offer.Source().HostAddress();
560563
info.Xid = _settings.Xid();

0 commit comments

Comments
 (0)