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 <cstdlib>
15
16#ifdef __WIN32__
17#include <WS2tcpip.h>
18#else
19#include <arpa/inet.h>
20#include <sys/socket.h>
21#endif
22
23namespace ns3
24{
25
26NS_LOG_COMPONENT_DEFINE("Ipv4Address");
27
29 : m_mask(0x66666666)
30{
31 NS_LOG_FUNCTION(this);
32}
33
35 : m_mask(mask)
36{
37 NS_LOG_FUNCTION(this << mask);
38}
39
40Ipv4Mask::Ipv4Mask(const char* mask)
41{
42 NS_LOG_FUNCTION(this << mask);
43 if (*mask == '/')
44 {
45 auto plen = static_cast<uint32_t>(std::atoi(++mask));
46 NS_ASSERT(plen <= 32);
47 if (plen > 0)
48 {
49 m_mask = 0xffffffff << (32 - plen);
50 }
51 else
52 {
53 m_mask = 0;
54 }
55 }
56 else
57 {
58 if (inet_pton(AF_INET, mask, &m_mask) <= 0)
59 {
60 NS_ABORT_MSG("Error, can not build an IPv4 mask from an invalid string: " << mask);
61 }
62 m_mask = ntohl(m_mask);
63 }
64}
65
66bool
68{
69 NS_LOG_FUNCTION(this << a << b);
70 return (a.Get() & m_mask) == (b.Get() & m_mask);
71}
72
75{
76 NS_LOG_FUNCTION(this);
77 return m_mask;
78}
79
80void
82{
83 NS_LOG_FUNCTION(this << mask);
84 m_mask = mask;
85}
86
89{
90 NS_LOG_FUNCTION(this);
91 return ~m_mask;
92}
93
94void
95Ipv4Mask::Print(std::ostream& os) const
96{
97 NS_LOG_FUNCTION(this << &os);
98 os << ((m_mask >> 24) & 0xff) << "." << ((m_mask >> 16) & 0xff) << "." << ((m_mask >> 8) & 0xff)
99 << "." << ((m_mask >> 0) & 0xff);
100}
101
104{
106 static Ipv4Mask loopback("255.0.0.0");
107 return loopback;
108}
109
112{
114 static Ipv4Mask zero("0.0.0.0");
115 return zero;
116}
117
120{
122 static Ipv4Mask ones("255.255.255.255");
123 return ones;
124}
125
126uint16_t
128{
129 NS_LOG_FUNCTION(this);
130 uint16_t tmp = 0;
131 uint32_t mask = m_mask;
132 while (mask != 0)
133 {
134 mask = mask << 1;
135 tmp++;
136 }
137 return tmp;
138}
139
140/**
141 * Value of a not-yet-initialized IPv4 address, corresponding to 102.102.102.102.
142 * This is totally arbitrary.
143 */
144static constexpr uint32_t UNINITIALIZED = 0x66666666U;
145
147 : m_address(UNINITIALIZED),
148 m_initialized(false)
149{
150 NS_LOG_FUNCTION(this);
151}
152
154{
155 NS_LOG_FUNCTION(this << address);
156 m_address = address;
157 m_initialized = true;
158}
159
160Ipv4Address::Ipv4Address(const char* address)
161{
162 NS_LOG_FUNCTION(this << address);
163
164 if (inet_pton(AF_INET, address, &m_address) <= 0)
165 {
166 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
167 m_address = 0;
168 m_initialized = false;
169 return;
170 }
171 m_initialized = true;
172 m_address = ntohl(m_address);
173}
174
177{
178 NS_LOG_FUNCTION(this);
179 return m_address;
180}
181
182void
184{
185 NS_LOG_FUNCTION(this << address);
186 m_address = address;
187 m_initialized = true;
188}
189
190void
191Ipv4Address::Set(const char* address)
192{
193 NS_LOG_FUNCTION(this << address);
194 if (inet_pton(AF_INET, address, &m_address) <= 0)
195 {
196 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
197 m_address = 0;
198 m_initialized = false;
199 return;
200 }
201 m_initialized = true;
202 m_address = ntohl(m_address);
203}
204
207{
208 NS_LOG_FUNCTION(this << mask);
209 return Ipv4Address(Get() & mask.Get());
210}
211
214{
215 NS_LOG_FUNCTION(this << mask);
216 if (mask == Ipv4Mask::GetOnes())
217 {
218 NS_ASSERT_MSG(false,
219 "Trying to get subnet-directed broadcast address with an all-ones netmask");
220 }
221 return Ipv4Address(Get() | mask.GetInverse());
222}
223
224bool
226{
227 NS_LOG_FUNCTION(this << mask);
228 if (mask == Ipv4Mask::GetOnes())
229 {
230 // If the mask is 255.255.255.255, there is no subnet directed
231 // broadcast for this address.
232 return false;
233 }
234 return ((Get() | mask.Get()) == Ipv4Address::GetBroadcast().Get());
235}
236
237bool
239{
240 NS_LOG_FUNCTION(this);
241 return m_initialized;
242}
243
244bool
246{
247 NS_LOG_FUNCTION(this);
248 return (m_address == 0x00000000U);
249}
250
251bool
253{
254 NS_LOG_FUNCTION(this);
255 return (m_address == 0x7f000001U);
256}
257
258bool
260{
261 NS_LOG_FUNCTION(this);
262 return (m_address == 0xffffffffU);
263}
264
265bool
267{
268 //
269 // Multicast addresses are defined as ranging from 224.0.0.0 through
270 // 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
271 //
272 NS_LOG_FUNCTION(this);
273 return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
274}
275
276bool
278{
279 NS_LOG_FUNCTION(this);
280 // Link-Local multicast address is 224.0.0.0/24
281 return (m_address & 0xffffff00) == 0xe0000000;
282}
283
284bool
286{
287 NS_LOG_FUNCTION(this);
288 // Link-Local address is 169.254.0.0/16
289 return (m_address & 0xffff0000) == 0xa9fe0000;
290}
291
292void
293Ipv4Address::Serialize(uint8_t buf[4]) const
294{
295 NS_LOG_FUNCTION(this << &buf);
296 buf[0] = (m_address >> 24) & 0xff;
297 buf[1] = (m_address >> 16) & 0xff;
298 buf[2] = (m_address >> 8) & 0xff;
299 buf[3] = (m_address >> 0) & 0xff;
300}
301
303Ipv4Address::Deserialize(const uint8_t buf[4])
304{
305 NS_LOG_FUNCTION(&buf);
306 Ipv4Address ipv4;
307 ipv4.m_address = 0;
308 ipv4.m_address |= buf[0];
309 ipv4.m_address <<= 8;
310 ipv4.m_address |= buf[1];
311 ipv4.m_address <<= 8;
312 ipv4.m_address |= buf[2];
313 ipv4.m_address <<= 8;
314 ipv4.m_address |= buf[3];
315 ipv4.m_initialized = true;
316
317 return ipv4;
318}
319
320void
321Ipv4Address::Print(std::ostream& os) const
322{
323 NS_LOG_FUNCTION(this);
324 os << ((m_address >> 24) & 0xff) << "." << ((m_address >> 16) & 0xff) << "."
325 << ((m_address >> 8) & 0xff) << "." << ((m_address >> 0) & 0xff);
326}
327
328bool
330{
331 NS_LOG_FUNCTION(&address);
332 return address.CheckCompatible(GetType(), 4);
333}
334
335Ipv4Address::operator Address() const
336{
337 return ConvertTo();
338}
339
342{
343 NS_LOG_FUNCTION(this);
344 uint8_t buf[4];
345 Serialize(buf);
346 return Address(GetType(), buf, 4);
347}
348
351{
352 NS_LOG_FUNCTION(&address);
353 NS_ASSERT(address.CheckCompatible(GetType(), 4));
354 uint8_t buf[4];
355 address.CopyTo(buf);
356 return Deserialize(buf);
357}
358
359uint8_t
361{
363 static uint8_t type = Address::Register();
364 return type;
365}
366
369{
371 static Ipv4Address zero("0.0.0.0");
372 return zero;
373}
374
377{
379 static Ipv4Address any("0.0.0.0");
380 return any;
381}
382
385{
387 static Ipv4Address broadcast("255.255.255.255");
388 return broadcast;
389}
390
393{
395 Ipv4Address loopback("127.0.0.1");
396 return loopback;
397}
398
399size_t
401{
402 return std::hash<uint32_t>()(x.Get());
403}
404
405std::ostream&
406operator<<(std::ostream& os, const Ipv4Address& address)
407{
408 address.Print(os);
409 return os;
410}
411
412std::ostream&
413operator<<(std::ostream& os, const Ipv4Mask& mask)
414{
415 mask.Print(os);
416 return os;
417}
418
419std::istream&
420operator>>(std::istream& is, Ipv4Address& address)
421{
422 std::string str;
423 is >> str;
424 address = Ipv4Address(str.c_str());
425 return is;
426}
427
428std::istream&
429operator>>(std::istream& is, Ipv4Mask& mask)
430{
431 std::string str;
432 is >> str;
433 mask = Ipv4Mask(str.c_str());
434 return is;
435}
436
439
440} // namespace ns3
a polymophic address class
Definition address.h:90
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition address.cc:135
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.
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).
bool m_initialized
IPv4 address has been explicitly initialized to a valid value.
uint32_t m_address
IPv4 address.
Address ConvertTo() const
Convert to an Address type.
bool IsBroadcast() const
static Ipv4Address GetAny()
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.
static Ipv4Mask GetOnes()
void Set(uint32_t mask)
input mask is in host order.
Ipv4Mask()
Will initialize to a garbage value (0x66666666)
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:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#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 ",...
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
static constexpr uint32_t UNINITIALIZED
Value of a not-yet-initialized IPv4 address, corresponding to 102.102.102.102.