A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
ipv4-address.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2005 INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
7 */
8
9#include "ipv4-address.h"
10
11#include "ns3/assert.h"
12#include "ns3/log.h"
13
14#include <bit>
15#include <cstdlib>
16
17#ifdef __WIN32__
18#include <WS2tcpip.h>
19#else
20#include <arpa/inet.h>
21#include <sys/socket.h>
22#endif
23
24namespace ns3
25{
26
27NS_LOG_COMPONENT_DEFINE("Ipv4Address");
28
30 : m_mask(mask)
31{
32 NS_LOG_FUNCTION(this << m_mask);
33 NS_ASSERT_MSG(IsValid(), "Invalid mask: " << m_mask);
34}
35
36Ipv4Mask::Ipv4Mask(const char* mask)
37{
38 NS_LOG_FUNCTION(this << mask);
39 if (*mask == '/')
40 {
41 auto plen = static_cast<uint32_t>(std::atoi(++mask));
42 NS_ASSERT(plen <= 32);
43 if (plen > 0)
44 {
45 m_mask = 0xffffffff << (32 - plen);
46 }
47 else
48 {
49 m_mask = 0;
50 }
51 }
52 else
53 {
54 if (inet_pton(AF_INET, mask, &m_mask) <= 0)
55 {
56 NS_ABORT_MSG("Error, can not build an IPv4 mask from an invalid string: " << mask);
57 }
58 m_mask = ntohl(m_mask);
59 NS_ASSERT_MSG(IsValid(), "Invalid mask: " << m_mask);
60 }
61}
62
63bool
65{
66 NS_LOG_FUNCTION(this << a << b);
67 return (a.Get() & m_mask) == (b.Get() & m_mask);
68}
69
72{
73 NS_LOG_FUNCTION(this);
74 return m_mask;
75}
76
77void
79{
80 NS_LOG_FUNCTION(this << mask);
81 m_mask = mask;
82 NS_ASSERT_MSG(IsValid(), "Invalid mask: " << m_mask);
83}
84
87{
88 NS_LOG_FUNCTION(this);
89 return ~m_mask;
90}
91
92void
93Ipv4Mask::Print(std::ostream& os) const
94{
95 NS_LOG_FUNCTION(this << &os);
96 os << ((m_mask >> 24) & 0xff) << "." << ((m_mask >> 16) & 0xff) << "." << ((m_mask >> 8) & 0xff)
97 << "." << ((m_mask >> 0) & 0xff);
98}
99
102{
104 static Ipv4Mask loopback("255.0.0.0");
105 return loopback;
106}
107
110{
112 static Ipv4Mask zero("0.0.0.0");
113 return zero;
114}
115
118{
120 static Ipv4Mask ones("255.255.255.255");
121 return ones;
122}
123
124uint16_t
126{
127 NS_LOG_FUNCTION(this);
128 uint16_t tmp = 0;
129 uint32_t mask = m_mask;
130 while (mask != 0)
131 {
132 mask = mask << 1;
133 tmp++;
134 }
135 return tmp;
136}
137
138constexpr bool
140{
141 return std::countl_one(m_mask) + std::countr_zero(m_mask) == 32;
142};
143
145{
146 NS_LOG_FUNCTION(this << address);
147 m_address = address;
148}
149
150Ipv4Address::Ipv4Address(const char* address)
151{
152 NS_LOG_FUNCTION(this << address);
153
154 if (inet_pton(AF_INET, address, &m_address) <= 0)
155 {
156 NS_ABORT_MSG("Error, can not build an IPv4 address from an invalid string: " << address);
157 return;
158 }
159 m_address = ntohl(m_address);
160}
161
162bool
163Ipv4Address::CheckCompatible(const std::string& addressStr)
164{
165 NS_LOG_FUNCTION(addressStr);
166
167 uint32_t buffer;
168
169 if (inet_pton(AF_INET, addressStr.c_str(), &buffer) <= 0)
170 {
171 NS_LOG_WARN("Error, can not build an IPv4 address from an invalid string: " << addressStr);
172 return false;
173 }
174 return true;
175}
176
179{
180 NS_LOG_FUNCTION(this);
181 return m_address;
182}
183
184void
186{
187 NS_LOG_FUNCTION(this << address);
188 m_address = address;
189}
190
191void
192Ipv4Address::Set(const char* address)
193{
194 NS_LOG_FUNCTION(this << address);
195 if (inet_pton(AF_INET, address, &m_address) <= 0)
196 {
197 NS_ABORT_MSG("Error, can not build an IPv4 address from an invalid string: " << address);
198 return;
199 }
200 m_address = ntohl(m_address);
201}
202
205{
206 NS_LOG_FUNCTION(this << mask);
207 return Ipv4Address(Get() & mask.Get());
208}
209
212{
213 NS_LOG_FUNCTION(this << mask);
214 if (mask == Ipv4Mask::GetOnes())
215 {
216 NS_ASSERT_MSG(false,
217 "Trying to get subnet-directed broadcast address with an all-ones netmask");
218 }
219 return Ipv4Address(Get() | mask.GetInverse());
220}
221
222bool
224{
225 NS_LOG_FUNCTION(this << mask);
226 if (mask == Ipv4Mask::GetOnes())
227 {
228 // If the mask is 255.255.255.255, there is no subnet directed
229 // broadcast for this address.
230 return false;
231 }
232 return ((Get() | mask.Get()) == Ipv4Address::GetBroadcast().Get());
233}
234
235bool
237{
238 NS_LOG_FUNCTION(this);
239 return true;
240}
241
242bool
244{
245 NS_LOG_FUNCTION(this);
246 return (m_address == 0x00000000U);
247}
248
249bool
251{
252 NS_LOG_FUNCTION(this);
253 return (m_address == 0x7f000001U);
254}
255
256bool
258{
259 NS_LOG_FUNCTION(this);
260 return (m_address == 0xffffffffU);
261}
262
263bool
265{
266 //
267 // Multicast addresses are defined as ranging from 224.0.0.0 through
268 // 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
269 //
270 NS_LOG_FUNCTION(this);
271 return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
272}
273
274bool
276{
277 NS_LOG_FUNCTION(this);
278 // Link-Local multicast address is 224.0.0.0/24
279 return (m_address & 0xffffff00) == 0xe0000000;
280}
281
282bool
284{
285 NS_LOG_FUNCTION(this);
286 // Link-Local address is 169.254.0.0/16
287 return (m_address & 0xffff0000) == 0xa9fe0000;
288}
289
290void
291Ipv4Address::Serialize(uint8_t buf[4]) const
292{
293 NS_LOG_FUNCTION(this << &buf);
294 buf[0] = (m_address >> 24) & 0xff;
295 buf[1] = (m_address >> 16) & 0xff;
296 buf[2] = (m_address >> 8) & 0xff;
297 buf[3] = (m_address >> 0) & 0xff;
298}
299
301Ipv4Address::Deserialize(const uint8_t buf[4])
302{
303 NS_LOG_FUNCTION(&buf);
304 Ipv4Address ipv4;
305 ipv4.m_address = 0;
306 ipv4.m_address |= buf[0];
307 ipv4.m_address <<= 8;
308 ipv4.m_address |= buf[1];
309 ipv4.m_address <<= 8;
310 ipv4.m_address |= buf[2];
311 ipv4.m_address <<= 8;
312 ipv4.m_address |= buf[3];
313
314 return ipv4;
315}
316
317void
318Ipv4Address::Print(std::ostream& os) const
319{
320 NS_LOG_FUNCTION(this);
321 os << ((m_address >> 24) & 0xff) << "." << ((m_address >> 16) & 0xff) << "."
322 << ((m_address >> 8) & 0xff) << "." << ((m_address >> 0) & 0xff);
323}
324
325bool
327{
328 NS_LOG_FUNCTION(&address);
329 return address.CheckCompatible(GetType(), 4);
330}
331
332Ipv4Address::
333operator Address() const
334{
335 return ConvertTo();
336}
337
340{
341 NS_LOG_FUNCTION(this);
342 uint8_t buf[4];
343 Serialize(buf);
344 return Address(GetType(), buf, 4);
345}
346
349{
350 NS_LOG_FUNCTION(&address);
351 NS_ASSERT(address.CheckCompatible(GetType(), 4));
352 uint8_t buf[4];
353 address.CopyTo(buf);
354 return Deserialize(buf);
355}
356
357uint8_t
359{
361 static uint8_t type = Address::Register("IpAddress", 4);
362 return type;
363}
364
367{
369 static Ipv4Address zero("0.0.0.0");
370 return zero;
371}
372
375{
377 static Ipv4Address any("0.0.0.0");
378 return any;
379}
380
383{
385 static Ipv4Address broadcast("255.255.255.255");
386 return broadcast;
387}
388
391{
393 Ipv4Address loopback("127.0.0.1");
394 return loopback;
395}
396
397size_t
399{
400 return std::hash<uint32_t>()(x.Get());
401}
402
403std::ostream&
404operator<<(std::ostream& os, const Ipv4Address& address)
405{
406 address.Print(os);
407 return os;
408}
409
410std::ostream&
411operator<<(std::ostream& os, const Ipv4Mask& mask)
412{
413 mask.Print(os);
414 return os;
415}
416
417std::istream&
418operator>>(std::istream& is, Ipv4Address& address)
419{
420 std::string str;
421 is >> str;
422 address = Ipv4Address(str.c_str());
423 return is;
424}
425
426std::istream&
427operator>>(std::istream& is, Ipv4Mask& mask)
428{
429 std::string str;
430 is >> str;
431 mask = Ipv4Mask(str.c_str());
432 return is;
433}
434
437
438} // namespace ns3
cairo_uint64_t x
_cairo_uint_96by64_32x64_divrem:
a polymophic address class
Definition address.h:114
static uint8_t Register(const std::string &kind, uint8_t length)
Allocate a new type id for a new type of address.
Definition address.cc:130
size_t operator()(const Ipv4Address &x) const
Returns the hash of an IPv4 address.
Ipv4 addresses are stored in host order in this class.
void Print(std::ostream &os) const
Print this address to the given output stream.
static Ipv4Address GetLoopback()
Ipv4Address GetSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
bool IsMulticast() const
static Ipv4Address ConvertFrom(const Address &address)
static Ipv4Address GetZero()
static bool IsMatchingType(const Address &address)
void Set(uint32_t address)
input address is in host order.
Ipv4Address()=default
bool IsSubnetDirectedBroadcast(const Ipv4Mask &mask) const
Generate subnet-directed broadcast address corresponding to mask.
bool IsLocalhost() const
static Ipv4Address GetBroadcast()
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
Ipv4Address CombineMask(const Ipv4Mask &mask) const
Combine this address with a network mask.
bool IsAny() const
uint32_t Get() const
Get the host-order 32-bit IP address.
static Ipv4Address Deserialize(const uint8_t buf[4])
static uint8_t GetType()
Get the underlying address type (automatically assigned).
uint32_t m_address
IPv4 address.
Address ConvertTo() const
Convert to an Address type.
bool IsBroadcast() const
static Ipv4Address GetAny()
static bool CheckCompatible(const std::string &addressStr)
Checks if the string contains an Ipv4Address.
bool IsInitialized() const
bool IsLocalMulticast() const
bool IsLinkLocal() const
If the IPv4 address is an APIPA address (169.254/16).
a class to represent an Ipv4 address mask
uint32_t m_mask
IP mask.
constexpr bool IsValid() const
Checks if the mask is valid, i.e., if it's in the form n-1 + m-0.
static Ipv4Mask GetOnes()
void Set(uint32_t mask)
input mask is in host order.
Ipv4Mask()=default
Will initialize to a zero-length mask, which will match any address.
uint16_t GetPrefixLength() const
uint32_t Get() const
Get the host-order 32-bit IP mask.
void Print(std::ostream &os) const
Print this mask to the given output stream.
uint32_t GetInverse() const
Return the inverse mask in host order.
bool IsMatch(Ipv4Address a, Ipv4Address b) const
static Ipv4Mask GetLoopback()
static Ipv4Mask GetZero()
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file,...
Definition assert.h:55
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition assert.h:75
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition abort.h:38
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:194
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:253
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148
std::istream & operator>>(std::istream &is, Angles &a)
Definition angles.cc:172