Skip to content

Commit 2e9eb18

Browse files
committed
internet-apps: use a std::array to store DHCP Chaddr
1 parent 980939b commit 2e9eb18

File tree

6 files changed

+100
-82
lines changed

6 files changed

+100
-82
lines changed

src/internet-apps/model/dhcp-client.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,12 @@ DhcpClient::StartApplication()
166166
// Moreover, the length is always 16, because chaddr is 16 bytes.
167167
Address myAddress = m_device->GetAddress();
168168
NS_LOG_INFO("My address is " << myAddress);
169-
uint8_t addr[Address::MAX_SIZE];
170-
std::memset(addr, 0, Address::MAX_SIZE);
171-
uint32_t len = myAddress.CopyTo(addr);
172-
NS_ASSERT_MSG(len <= 16, "DHCP client can not handle a chaddr larger than 16 bytes");
173-
m_chaddr.CopyFrom(addr, 16);
174-
NS_LOG_INFO("My m_chaddr is " << m_chaddr);
169+
NS_ASSERT_MSG(myAddress.GetLength() <= 16,
170+
"DHCP client can not handle a chaddr larger than 16 bytes");
171+
172+
m_chaddr.fill(0);
173+
myAddress.CopyTo(m_chaddr.begin());
174+
NS_LOG_INFO("My Chaddr is " << DhcpChaddrToString(m_chaddr));
175175

176176
bool found = false;
177177
for (uint32_t i = 0; i < ipv4->GetNAddresses(ifIndex); i++)

src/internet-apps/model/dhcp-client.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class DhcpClient : public Application
140140
Ipv4Address m_remoteAddress; //!< Initially set to 255.255.255.255 to start DHCP
141141
Ipv4Address m_offeredAddress; //!< Address offered to the client
142142
Ipv4Address m_myAddress; //!< Address assigned to the client
143-
Address m_chaddr; //!< chaddr of the interface (stored as an Address for convenience).
143+
DhcpChaddr m_chaddr{}; //!< chaddr of the interface (stored as an Address for convenience).
144144
Ipv4Mask m_myMask; //!< Mask of the address assigned
145145
Ipv4Address m_server; //!< Address of the DHCP server
146146
Ipv4Address m_gateway; //!< Address of the gateway

src/internet-apps/model/dhcp-header.cc

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,35 @@
1717
#include "ns3/log.h"
1818
#include "ns3/simulator.h"
1919

20+
#include <iomanip>
21+
#include <sstream>
22+
23+
/**
24+
* @file
25+
* @ingroup internet-apps
26+
* DhcpHeader classes implementation.
27+
*/
28+
2029
namespace ns3
2130
{
2231

2332
NS_LOG_COMPONENT_DEFINE("DhcpHeader");
2433
NS_OBJECT_ENSURE_REGISTERED(DhcpHeader);
2534

35+
std::string
36+
DhcpChaddrToString(const DhcpChaddr& chaddr)
37+
{
38+
std::ostringstream outStream;
39+
outStream.fill('0');
40+
outStream.setf(std::ios::hex, std::ios::basefield);
41+
42+
for (std::size_t i = 0; i < chaddr.size(); ++i)
43+
{
44+
outStream << std::setw(2) << (uint32_t)chaddr[i] << (i < chaddr.size() - 1 ? ":" : "");
45+
}
46+
return outStream.str();
47+
}
48+
2649
DhcpHeader::DhcpHeader()
2750
{
2851
m_hType = 1;
@@ -105,27 +128,15 @@ DhcpHeader::SetTime()
105128
}
106129

107130
void
108-
DhcpHeader::SetChaddr(Address addr)
109-
{
110-
std::memset(m_chaddr, 0, 16);
111-
NS_ASSERT_MSG(addr.GetLength() <= 16, "Address length too big");
112-
addr.CopyTo(m_chaddr);
113-
}
114-
115-
void
116-
DhcpHeader::SetChaddr(uint8_t* addr, uint8_t len)
131+
DhcpHeader::SetChaddr(DhcpChaddr addr)
117132
{
118-
std::memset(m_chaddr, 0, 16);
119-
NS_ASSERT_MSG(len <= 16, "Address length too big");
120-
std::memcpy(m_chaddr, addr, len);
133+
m_chaddr = addr;
121134
}
122135

123-
Address
136+
DhcpChaddr
124137
DhcpHeader::GetChaddr()
125138
{
126-
Address addr;
127-
addr.CopyFrom(m_chaddr, 16);
128-
return addr;
139+
return m_chaddr;
129140
}
130141

131142
void
@@ -313,7 +324,7 @@ DhcpHeader::Serialize(Buffer::Iterator start) const
313324
WriteTo(i, m_yiAddr);
314325
WriteTo(i, m_siAddr);
315326
WriteTo(i, m_giAddr);
316-
i.Write(m_chaddr, 16);
327+
i.Write(m_chaddr.data(), 16);
317328
i.Write(m_sname, 64);
318329
i.Write(m_file, 128);
319330
i.Write(m_magic_cookie, 4);
@@ -390,7 +401,7 @@ DhcpHeader::Deserialize(Buffer::Iterator start)
390401
ReadFrom(i, m_yiAddr);
391402
ReadFrom(i, m_siAddr);
392403
ReadFrom(i, m_giAddr);
393-
i.Read(m_chaddr, 16);
404+
i.Read(m_chaddr.data(), 16);
394405
i.Read(m_sname, 64);
395406
i.Read(m_file, 128);
396407
i.Read(m_magic_cookie, 4);

src/internet-apps/model/dhcp-header.h

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
#include "ns3/header.h"
1919
#include "ns3/ipv4-address.h"
2020

21+
/**
22+
* @file
23+
* @ingroup internet-apps
24+
* DhcpHeader classes declaration
25+
*/
26+
2127
namespace ns3
2228
{
2329

@@ -26,6 +32,24 @@ namespace ns3
2632
* @defgroup dhcp DHCPv4 Client and Server
2733
*/
2834

35+
/**
36+
* @ingroup dhcp
37+
*
38+
* This is the Chaddr field, which is 16 bytes long. Originally it was
39+
* meant to hold the Client Hardware Address (hence the name), but later RFCs
40+
* refers to it just as the Client Identifier.
41+
*/
42+
using DhcpChaddr = std::array<uint8_t, 16>;
43+
44+
/**
45+
* @ingroup dhcp
46+
* Function to pretty-print a Chaddr.
47+
*
48+
* @param chaddr the Chaddr
49+
* @return A formatted string
50+
*/
51+
std::string DhcpChaddrToString(const DhcpChaddr& chaddr);
52+
2953
/**
3054
* @ingroup dhcp
3155
*
@@ -149,20 +173,11 @@ class DhcpHeader : public Header
149173
void SetTime();
150174

151175
/**
152-
* @brief Set the Address of the device.
153-
*
154-
* Only the relevant bits are considered (i.e., not the type and length)
176+
* @brief Set the Chaddress of the device.
155177
*
156178
* @param addr Address of the device
157179
*/
158-
void SetChaddr(Address addr);
159-
160-
/**
161-
* @brief Set the Address of the device
162-
* @param addr Address of the device
163-
* @param len Address length
164-
*/
165-
void SetChaddr(uint8_t* addr, uint8_t len);
180+
void SetChaddr(DhcpChaddr addr);
166181

167182
/**
168183
* @brief Get the Address of the client.
@@ -171,7 +186,7 @@ class DhcpHeader : public Header
171186
*
172187
* @return Address of the client
173188
*/
174-
Address GetChaddr();
189+
DhcpChaddr GetChaddr();
175190

176191
/**
177192
* @brief Set the IPv4Address of the client
@@ -291,7 +306,7 @@ class DhcpHeader : public Header
291306
uint32_t m_len; //!< The length of the header
292307
uint16_t m_secs; //!< Seconds elapsed
293308
uint16_t m_flags; //!< BOOTP flags
294-
uint8_t m_chaddr[16]; //!< The address identifier
309+
DhcpChaddr m_chaddr; //!< The client identifier
295310
Ipv4Address m_yiAddr; //!< Your (client) IP address
296311
Ipv4Address m_ciAddr; //!< The IP address of the client
297312
Ipv4Address m_siAddr; //!< Next Server IP address

src/internet-apps/model/dhcp-server.cc

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "ns3/socket.h"
2525

2626
#include <algorithm>
27+
#include <limits>
2728

2829
namespace ns3
2930
{
@@ -133,7 +134,8 @@ DhcpServer::StartApplication()
133134
// set infinite GRANTED_LEASED_TIME for my address
134135

135136
myOwnAddress = ipv4->GetAddress(ifIndex, addrIndex).GetLocal();
136-
m_leasedAddresses[Address()] = std::make_pair(myOwnAddress, 0xffffffff);
137+
DhcpChaddr null = {};
138+
m_leasedAddresses[null] = std::make_pair(myOwnAddress, PERMANENT_LEASE);
137139
break;
138140
}
139141
}
@@ -181,19 +183,18 @@ DhcpServer::TimerHandler()
181183
NS_LOG_FUNCTION(this);
182184

183185
// Set up timeout events and release of unsolicited addresses from the list
184-
LeasedAddressIter i;
185-
for (i = m_leasedAddresses.begin(); i != m_leasedAddresses.end(); i++)
186+
for (auto [k, v] : m_leasedAddresses)
186187
{
187188
// update the address state
188-
if (i->second.second != 0xffffffff && i->second.second != 0)
189+
if (v.second != PERMANENT_LEASE && v.second != 0)
189190
{
190-
i->second.second--;
191-
if (i->second.second == 0)
191+
v.second--;
192+
if (v.second == 0)
192193
{
193194
NS_LOG_INFO("Address leased state expired, address removed - "
194-
<< "chaddr: " << i->first << " IP address " << i->second.first);
195-
i->second.second = 0;
196-
m_expiredAddresses.push_front(i->first);
195+
<< "chaddr: " << DhcpChaddrToString(k) << " IP address " << v.first);
196+
v.second = 0;
197+
m_expiredAddresses.push_front(k);
197198
}
198199
}
199200
}
@@ -241,7 +242,7 @@ DhcpServer::SendOffer(Ptr<NetDevice> iDev, DhcpHeader header, InetSocketAddress
241242
NS_LOG_FUNCTION(this << iDev << header << from);
242243

243244
DhcpHeader newDhcpHeader;
244-
Address sourceChaddr = header.GetChaddr();
245+
DhcpChaddr sourceChaddr = header.GetChaddr();
245246
uint32_t tran = header.GetTran();
246247
Ptr<Packet> packet = nullptr;
247248
Ipv4Address offeredAddress;
@@ -253,11 +254,11 @@ DhcpServer::SendOffer(Ptr<NetDevice> iDev, DhcpHeader header, InetSocketAddress
253254
{
254255
// We know this client from some time ago
255256
if (m_leasedAddresses[sourceChaddr].second != 0 &&
256-
m_leasedAddresses[sourceChaddr].second != 0xffffffff)
257+
m_leasedAddresses[sourceChaddr].second != PERMANENT_LEASE)
257258
{
258259
NS_LOG_LOGIC("This client is sending a DISCOVER but it has still a lease active - "
259260
"perhaps it didn't shut down gracefully: "
260-
<< sourceChaddr);
261+
<< DhcpChaddrToString(sourceChaddr));
261262
}
262263

263264
m_expiredAddresses.remove(sourceChaddr);
@@ -277,7 +278,7 @@ DhcpServer::SendOffer(Ptr<NetDevice> iDev, DhcpHeader header, InetSocketAddress
277278
// there's still hope: reuse the old ones.
278279
if (!m_expiredAddresses.empty())
279280
{
280-
Address oldestChaddr = m_expiredAddresses.back();
281+
DhcpChaddr oldestChaddr = m_expiredAddresses.back();
281282
m_expiredAddresses.pop_back();
282283
offeredAddress = m_leasedAddresses[oldestChaddr].first;
283284
m_leasedAddresses.erase(oldestChaddr);
@@ -334,16 +335,15 @@ DhcpServer::SendAck(Ptr<NetDevice> iDev, DhcpHeader header, InetSocketAddress fr
334335
NS_LOG_FUNCTION(this << iDev << header << from);
335336

336337
DhcpHeader newDhcpHeader;
337-
Address sourceChaddr = header.GetChaddr();
338+
DhcpChaddr sourceChaddr = header.GetChaddr();
338339
uint32_t tran = header.GetTran();
339340
Ptr<Packet> packet = nullptr;
340341
Ipv4Address address = header.GetReq();
341342

342343
NS_LOG_INFO("DHCP REQUEST from: " << from.GetIpv4() << " source port: " << from.GetPort()
343344
<< " - refreshed addr: " << address);
344345

345-
LeasedAddressIter iter;
346-
iter = m_leasedAddresses.find(sourceChaddr);
346+
auto iter = m_leasedAddresses.find(sourceChaddr);
347347
if (iter != m_leasedAddresses.end())
348348
{
349349
// update the lease time of this address - send ACK
@@ -393,33 +393,29 @@ DhcpServer::SendAck(Ptr<NetDevice> iDev, DhcpHeader header, InetSocketAddress fr
393393
}
394394

395395
void
396-
DhcpServer::AddStaticDhcpEntry(Address chaddr, Ipv4Address addr)
396+
DhcpServer::AddStaticDhcpEntry(Address macAddr, Ipv4Address addr)
397397
{
398-
NS_LOG_FUNCTION(this << chaddr << addr);
399-
Address cleanedCaddr;
398+
NS_LOG_FUNCTION(this << macAddr << addr);
399+
DhcpChaddr chAddr{};
400400

401401
NS_ASSERT_MSG(addr.Get() >= m_minAddress.Get() && addr.Get() <= m_maxAddress.Get(),
402402
"Required address is not in the pool " << addr << " is not in [" << m_minAddress
403403
<< ", " << m_maxAddress << "]");
404+
NS_ASSERT_MSG(macAddr.GetLength() <= 16,
405+
"DHCP server can not handle a chaddr larger than 16 bytes");
406+
macAddr.CopyTo(chAddr.begin());
404407

405-
// We need to cleanup the type from the stored chaddr, or later we'll fail to compare it.
406-
// Moreover, the length is always 16, because chaddr is 16 bytes.
407-
uint8_t buffer[Address::MAX_SIZE];
408-
std::memset(buffer, 0, Address::MAX_SIZE);
409-
uint32_t len = chaddr.CopyTo(buffer);
410-
NS_ASSERT_MSG(len <= 16, "DHCP server can not handle a chaddr larger than 16 bytes");
411-
cleanedCaddr.CopyFrom(buffer, 16);
412-
413-
NS_ASSERT_MSG(m_leasedAddresses.find(cleanedCaddr) == m_leasedAddresses.end(),
414-
"Client has already an active lease: " << m_leasedAddresses[cleanedCaddr].first);
408+
NS_ASSERT_MSG(m_leasedAddresses.find(chAddr) == m_leasedAddresses.end(),
409+
"Client has already an active lease: " << m_leasedAddresses[chAddr].first);
415410

416411
auto it = find(m_availableAddresses.begin(), m_availableAddresses.end(), addr);
417412
NS_ASSERT_MSG(
418413
it == m_availableAddresses.end(),
419414
"Required address is not available (perhaps it has been already assigned): " << addr);
420415

421416
m_availableAddresses.remove(addr);
422-
m_leasedAddresses[cleanedCaddr] = std::make_pair(addr, 0xffffffff);
417+
NS_LOG_INFO("Added a static lease for " << DhcpChaddrToString(chAddr) << " -> " << addr);
418+
m_leasedAddresses[chAddr] = std::make_pair(addr, PERMANENT_LEASE);
423419
}
424420

425421
} // Namespace ns3

src/internet-apps/model/dhcp-server.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "ns3/application.h"
1919
#include "ns3/ipv4-address.h"
2020

21+
#include <limits>
2122
#include <map>
2223

2324
namespace ns3
@@ -48,10 +49,10 @@ class DhcpServer : public Application
4849
/**
4950
* @brief Add a static entry to the pool.
5051
*
51-
* @param chaddr The client chaddr.
52-
* @param addr The address to handle to the client.
52+
* @param macAddr The client MAC address.
53+
* @param addr The IP address to handle to the client.
5354
*/
54-
void AddStaticDhcpEntry(Address chaddr, Ipv4Address addr);
55+
void AddStaticDhcpEntry(Address macAddr, Ipv4Address addr);
5556

5657
protected:
5758
void DoDispose() override;
@@ -97,21 +98,16 @@ class DhcpServer : public Application
9798
Ipv4Address m_gateway; //!< The gateway address
9899

99100
/// Leased address container - chaddr + IP addr / lease time
100-
typedef std::map<Address, std::pair<Ipv4Address, uint32_t>> LeasedAddress;
101-
/// Leased address iterator - chaddr + IP addr / lease time
102-
typedef std::map<Address, std::pair<Ipv4Address, uint32_t>>::iterator LeasedAddressIter;
103-
/// Leased address const iterator - chaddr + IP addr / lease time
104-
typedef std::map<Address, std::pair<Ipv4Address, uint32_t>>::const_iterator LeasedAddressCIter;
101+
using LeasedAddress = std::map<DhcpChaddr, std::pair<Ipv4Address, uint32_t>>;
105102

106103
/// Expired address container - chaddr
107-
typedef std::list<Address> ExpiredAddress;
108-
/// Expired address iterator - chaddr
109-
typedef std::list<Address>::iterator ExpiredAddressIter;
110-
/// Expired address const iterator - chaddr
111-
typedef std::list<Address>::const_iterator ExpiredAddressCIter;
104+
using ExpiredAddress = std::list<DhcpChaddr>;
112105

113106
/// Available address container - IP addr
114-
typedef std::list<Ipv4Address> AvailableAddress;
107+
using AvailableAddress = std::list<Ipv4Address>;
108+
109+
/// The maximum representable lease time means permanent lease.
110+
static constexpr uint32_t PERMANENT_LEASE = std::numeric_limits<uint32_t>::max();
115111

116112
LeasedAddress m_leasedAddresses; //!< Leased address and their status (cache memory)
117113
ExpiredAddress m_expiredAddresses; //!< Expired addresses to be reused (chaddr of the clients)

0 commit comments

Comments
 (0)