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
284void
285Ipv4Address::Serialize(uint8_t buf[4]) const
286{
287 NS_LOG_FUNCTION(this << &buf);
288 buf[0] = (m_address >> 24) & 0xff;
289 buf[1] = (m_address >> 16) & 0xff;
290 buf[2] = (m_address >> 8) & 0xff;
291 buf[3] = (m_address >> 0) & 0xff;
292}
293
295Ipv4Address::Deserialize(const uint8_t buf[4])
296{
297 NS_LOG_FUNCTION(&buf);
298 Ipv4Address ipv4;
299 ipv4.m_address = 0;
300 ipv4.m_address |= buf[0];
301 ipv4.m_address <<= 8;
302 ipv4.m_address |= buf[1];
303 ipv4.m_address <<= 8;
304 ipv4.m_address |= buf[2];
305 ipv4.m_address <<= 8;
306 ipv4.m_address |= buf[3];
307 ipv4.m_initialized = true;
308
309 return ipv4;
310}
311
312void
313Ipv4Address::Print(std::ostream& os) const
314{
315 NS_LOG_FUNCTION(this);
316 os << ((m_address >> 24) & 0xff) << "." << ((m_address >> 16) & 0xff) << "."
317 << ((m_address >> 8) & 0xff) << "." << ((m_address >> 0) & 0xff);
318}
319
320bool
322{
323 NS_LOG_FUNCTION(&address);
324 return address.CheckCompatible(GetType(), 4);
325}
326
327Ipv4Address::operator Address() const
328{
329 return ConvertTo();
330}
331
334{
335 NS_LOG_FUNCTION(this);
336 uint8_t buf[4];
337 Serialize(buf);
338 return Address(GetType(), buf, 4);
339}
340
343{
344 NS_LOG_FUNCTION(&address);
345 NS_ASSERT(address.CheckCompatible(GetType(), 4));
346 uint8_t buf[4];
347 address.CopyTo(buf);
348 return Deserialize(buf);
349}
350
351uint8_t
353{
355 static uint8_t type = Address::Register();
356 return type;
357}
358
361{
363 static Ipv4Address zero("0.0.0.0");
364 return zero;
365}
366
369{
371 static Ipv4Address any("0.0.0.0");
372 return any;
373}
374
377{
379 static Ipv4Address broadcast("255.255.255.255");
380 return broadcast;
381}
382
385{
387 Ipv4Address loopback("127.0.0.1");
388 return loopback;
389}
390
391size_t
393{
394 return std::hash<uint32_t>()(x.Get());
395}
396
397std::ostream&
398operator<<(std::ostream& os, const Ipv4Address& address)
399{
400 address.Print(os);
401 return os;
402}
403
404std::ostream&
405operator<<(std::ostream& os, const Ipv4Mask& mask)
406{
407 mask.Print(os);
408 return os;
409}
410
411std::istream&
412operator>>(std::istream& is, Ipv4Address& address)
413{
414 std::string str;
415 is >> str;
416 address = Ipv4Address(str.c_str());
417 return is;
418}
419
420std::istream&
421operator>>(std::istream& is, Ipv4Mask& mask)
422{
423 std::string str;
424 is >> str;
425 mask = Ipv4Mask(str.c_str());
426 return is;
427}
428
431
432} // 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
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()
static double zero
#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.