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 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
18 */
19
20#include "ipv4-address.h"
21
22#include "ns3/assert.h"
23#include "ns3/log.h"
24
25#include <cstdlib>
26
27#ifdef __WIN32__
28#include <WS2tcpip.h>
29#else
30#include <arpa/inet.h>
31#endif
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("Ipv4Address");
37
39 : m_mask(0x66666666)
40{
41 NS_LOG_FUNCTION(this);
42}
43
45 : m_mask(mask)
46{
47 NS_LOG_FUNCTION(this << mask);
48}
49
50Ipv4Mask::Ipv4Mask(const char* mask)
51{
52 NS_LOG_FUNCTION(this << mask);
53 if (*mask == '/')
54 {
55 auto plen = static_cast<uint32_t>(std::atoi(++mask));
56 NS_ASSERT(plen <= 32);
57 if (plen > 0)
58 {
59 m_mask = 0xffffffff << (32 - plen);
60 }
61 else
62 {
63 m_mask = 0;
64 }
65 }
66 else
67 {
68 if (inet_pton(AF_INET, mask, &m_mask) <= 0)
69 {
70 NS_ABORT_MSG("Error, can not build an IPv4 mask from an invalid string: " << mask);
71 }
72 m_mask = ntohl(m_mask);
73 }
74}
75
76bool
78{
79 NS_LOG_FUNCTION(this << a << b);
80 return (a.Get() & m_mask) == (b.Get() & m_mask);
81}
82
85{
86 NS_LOG_FUNCTION(this);
87 return m_mask;
88}
89
90void
92{
93 NS_LOG_FUNCTION(this << mask);
94 m_mask = mask;
95}
96
99{
100 NS_LOG_FUNCTION(this);
101 return ~m_mask;
102}
103
104void
105Ipv4Mask::Print(std::ostream& os) const
106{
107 NS_LOG_FUNCTION(this << &os);
108 os << ((m_mask >> 24) & 0xff) << "." << ((m_mask >> 16) & 0xff) << "." << ((m_mask >> 8) & 0xff)
109 << "." << ((m_mask >> 0) & 0xff);
110}
111
114{
116 static Ipv4Mask loopback("255.0.0.0");
117 return loopback;
118}
119
122{
124 static Ipv4Mask zero("0.0.0.0");
125 return zero;
126}
127
130{
132 static Ipv4Mask ones("255.255.255.255");
133 return ones;
134}
135
136uint16_t
138{
139 NS_LOG_FUNCTION(this);
140 uint16_t tmp = 0;
141 uint32_t mask = m_mask;
142 while (mask != 0)
143 {
144 mask = mask << 1;
145 tmp++;
146 }
147 return tmp;
148}
149
154static constexpr uint32_t UNINITIALIZED = 0x66666666U;
155
157 : m_address(UNINITIALIZED),
158 m_initialized(false)
159{
160 NS_LOG_FUNCTION(this);
161}
162
164{
165 NS_LOG_FUNCTION(this << address);
166 m_address = address;
167 m_initialized = true;
168}
169
170Ipv4Address::Ipv4Address(const char* address)
171{
172 NS_LOG_FUNCTION(this << address);
173
174 if (inet_pton(AF_INET, address, &m_address) <= 0)
175 {
176 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
177 m_address = 0;
178 m_initialized = false;
179 return;
180 }
181 m_initialized = true;
182 m_address = ntohl(m_address);
183}
184
187{
188 NS_LOG_FUNCTION(this);
189 return m_address;
190}
191
192void
194{
195 NS_LOG_FUNCTION(this << address);
196 m_address = address;
197 m_initialized = true;
198}
199
200void
201Ipv4Address::Set(const char* address)
202{
203 NS_LOG_FUNCTION(this << address);
204 if (inet_pton(AF_INET, address, &m_address) <= 0)
205 {
206 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
207 m_address = 0;
208 m_initialized = false;
209 return;
210 }
211 m_initialized = true;
212 m_address = ntohl(m_address);
213}
214
217{
218 NS_LOG_FUNCTION(this << mask);
219 return Ipv4Address(Get() & mask.Get());
220}
221
224{
225 NS_LOG_FUNCTION(this << mask);
226 if (mask == Ipv4Mask::GetOnes())
227 {
228 NS_ASSERT_MSG(false,
229 "Trying to get subnet-directed broadcast address with an all-ones netmask");
230 }
231 return Ipv4Address(Get() | mask.GetInverse());
232}
233
234bool
236{
237 NS_LOG_FUNCTION(this << mask);
238 if (mask == Ipv4Mask::GetOnes())
239 {
240 // If the mask is 255.255.255.255, there is no subnet directed
241 // broadcast for this address.
242 return false;
243 }
244 return ((Get() | mask.Get()) == Ipv4Address::GetBroadcast().Get());
245}
246
247bool
249{
250 NS_LOG_FUNCTION(this);
251 return m_initialized;
252}
253
254bool
256{
257 NS_LOG_FUNCTION(this);
258 return (m_address == 0x00000000U);
259}
260
261bool
263{
264 NS_LOG_FUNCTION(this);
265 return (m_address == 0x7f000001U);
266}
267
268bool
270{
271 NS_LOG_FUNCTION(this);
272 return (m_address == 0xffffffffU);
273}
274
275bool
277{
278 //
279 // Multicast addresses are defined as ranging from 224.0.0.0 through
280 // 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
281 //
282 NS_LOG_FUNCTION(this);
283 return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
284}
285
286bool
288{
289 NS_LOG_FUNCTION(this);
290 // Link-Local multicast address is 224.0.0.0/24
291 return (m_address & 0xffffff00) == 0xe0000000;
292}
293
294void
295Ipv4Address::Serialize(uint8_t buf[4]) const
296{
297 NS_LOG_FUNCTION(this << &buf);
298 buf[0] = (m_address >> 24) & 0xff;
299 buf[1] = (m_address >> 16) & 0xff;
300 buf[2] = (m_address >> 8) & 0xff;
301 buf[3] = (m_address >> 0) & 0xff;
302}
303
305Ipv4Address::Deserialize(const uint8_t buf[4])
306{
307 NS_LOG_FUNCTION(&buf);
308 Ipv4Address ipv4;
309 ipv4.m_address = 0;
310 ipv4.m_address |= buf[0];
311 ipv4.m_address <<= 8;
312 ipv4.m_address |= buf[1];
313 ipv4.m_address <<= 8;
314 ipv4.m_address |= buf[2];
315 ipv4.m_address <<= 8;
316 ipv4.m_address |= buf[3];
317 ipv4.m_initialized = true;
318
319 return ipv4;
320}
321
322void
323Ipv4Address::Print(std::ostream& os) const
324{
325 NS_LOG_FUNCTION(this);
326 os << ((m_address >> 24) & 0xff) << "." << ((m_address >> 16) & 0xff) << "."
327 << ((m_address >> 8) & 0xff) << "." << ((m_address >> 0) & 0xff);
328}
329
330bool
332{
333 NS_LOG_FUNCTION(&address);
334 return address.CheckCompatible(GetType(), 4);
335}
336
337Ipv4Address::operator Address() const
338{
339 return ConvertTo();
340}
341
344{
345 NS_LOG_FUNCTION(this);
346 uint8_t buf[4];
347 Serialize(buf);
348 return Address(GetType(), buf, 4);
349}
350
353{
354 NS_LOG_FUNCTION(&address);
355 NS_ASSERT(address.CheckCompatible(GetType(), 4));
356 uint8_t buf[4];
357 address.CopyTo(buf);
358 return Deserialize(buf);
359}
360
361uint8_t
363{
365 static uint8_t type = Address::Register();
366 return type;
367}
368
371{
373 static Ipv4Address zero("0.0.0.0");
374 return zero;
375}
376
379{
381 static Ipv4Address any("0.0.0.0");
382 return any;
383}
384
387{
389 static Ipv4Address broadcast("255.255.255.255");
390 return broadcast;
391}
392
395{
397 Ipv4Address loopback("127.0.0.1");
398 return loopback;
399}
400
401size_t
403{
404 return std::hash<uint32_t>()(x.Get());
405}
406
407std::ostream&
408operator<<(std::ostream& os, const Ipv4Address& address)
409{
410 address.Print(os);
411 return os;
412}
413
414std::ostream&
415operator<<(std::ostream& os, const Ipv4Mask& mask)
416{
417 mask.Print(os);
418 return os;
419}
420
421std::istream&
422operator>>(std::istream& is, Ipv4Address& address)
423{
424 std::string str;
425 is >> str;
426 address = Ipv4Address(str.c_str());
427 return is;
428}
429
430std::istream&
431operator>>(std::istream& is, Ipv4Mask& mask)
432{
433 std::string str;
434 is >> str;
435 mask = Ipv4Mask(str.c_str());
436 return is;
437}
438
441
442} // namespace ns3
a polymophic address class
Definition: address.h:101
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition: address.cc:146
size_t operator()(const Ipv4Address &x) const
Returns the hash of an IPv4 address.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:42
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.
Definition: ipv4-address.h:215
uint32_t m_address
IPv4 address.
Definition: ipv4-address.h:214
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
Definition: ipv4-address.h:257
uint32_t m_mask
IP mask.
Definition: ipv4-address.h:338
static Ipv4Mask GetOnes()
void Set(uint32_t mask)
input mask is in host order.
Definition: ipv4-address.cc:91
Ipv4Mask()
Will initialize to a garbage value (0x66666666)
Definition: ipv4-address.cc:38
uint16_t GetPrefixLength() const
uint32_t Get() const
Get the host-order 32-bit IP mask.
Definition: ipv4-address.cc:84
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.
Definition: ipv4-address.cc:98
bool IsMatch(Ipv4Address a, Ipv4Address b) const
Definition: ipv4-address.cc:77
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:66
#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:86
#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:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:159
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:183
static constexpr uint32_t UNINITIALIZED
Value of a not-yet-initialized IPv4 address, corresponding to 102.102.102.102.