A Discrete-Event Network Simulator
API
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 uint32_t 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 if ((a.Get() & m_mask) == (b.Get() & m_mask))
81 {
82 return true;
83 }
84 else
85 {
86 return false;
87 }
88}
89
92{
93 NS_LOG_FUNCTION(this);
94 return m_mask;
95}
96
97void
99{
100 NS_LOG_FUNCTION(this << mask);
101 m_mask = mask;
102}
103
106{
107 NS_LOG_FUNCTION(this);
108 return ~m_mask;
109}
110
111void
112Ipv4Mask::Print(std::ostream& os) const
113{
114 NS_LOG_FUNCTION(this << &os);
115 os << ((m_mask >> 24) & 0xff) << "." << ((m_mask >> 16) & 0xff) << "." << ((m_mask >> 8) & 0xff)
116 << "." << ((m_mask >> 0) & 0xff);
117}
118
121{
123 static Ipv4Mask loopback = Ipv4Mask("255.0.0.0");
124 return loopback;
125}
126
129{
131 static Ipv4Mask zero = Ipv4Mask("0.0.0.0");
132 return zero;
133}
134
137{
139 static Ipv4Mask ones = Ipv4Mask("255.255.255.255");
140 return ones;
141}
142
143uint16_t
145{
146 NS_LOG_FUNCTION(this);
147 uint16_t tmp = 0;
148 uint32_t mask = m_mask;
149 while (mask != 0)
150 {
151 mask = mask << 1;
152 tmp++;
153 }
154 return tmp;
155}
156
161static constexpr uint32_t UNINITIALIZED = 0x66666666U;
162
164 : m_address(UNINITIALIZED),
165 m_initialized(false)
166{
167 NS_LOG_FUNCTION(this);
168}
169
171{
172 NS_LOG_FUNCTION(this << address);
174 m_initialized = true;
175}
176
178{
179 NS_LOG_FUNCTION(this << address);
180
181 if (inet_pton(AF_INET, address, &m_address) <= 0)
182 {
183 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
184 m_address = 0;
185 m_initialized = false;
186 return;
187 }
188 m_initialized = true;
189 m_address = ntohl(m_address);
190}
191
194{
195 NS_LOG_FUNCTION(this);
196 return m_address;
197}
198
199void
201{
202 NS_LOG_FUNCTION(this << address);
204 m_initialized = true;
205}
206
207void
209{
210 NS_LOG_FUNCTION(this << address);
211 if (inet_pton(AF_INET, address, &m_address) <= 0)
212 {
213 NS_LOG_LOGIC("Error, can not build an IPv4 address from an invalid string: " << address);
214 m_address = 0;
215 m_initialized = false;
216 return;
217 }
218 m_initialized = true;
219 m_address = ntohl(m_address);
220}
221
224{
225 NS_LOG_FUNCTION(this << mask);
226 return Ipv4Address(Get() & mask.Get());
227}
228
231{
232 NS_LOG_FUNCTION(this << mask);
233 if (mask == Ipv4Mask::GetOnes())
234 {
235 NS_ASSERT_MSG(false,
236 "Trying to get subnet-directed broadcast address with an all-ones netmask");
237 }
238 return Ipv4Address(Get() | mask.GetInverse());
239}
240
241bool
243{
244 NS_LOG_FUNCTION(this << mask);
245 if (mask == Ipv4Mask::GetOnes())
246 {
247 // If the mask is 255.255.255.255, there is no subnet directed
248 // broadcast for this address.
249 return false;
250 }
251 return ((Get() | mask.Get()) == Ipv4Address::GetBroadcast().Get());
252}
253
254bool
256{
257 NS_LOG_FUNCTION(this);
258 return (m_initialized);
259}
260
261bool
263{
264 NS_LOG_FUNCTION(this);
265 return (m_address == 0x00000000U);
266}
267
268bool
270{
271 NS_LOG_FUNCTION(this);
272 return (m_address == 0x7f000001U);
273}
274
275bool
277{
278 NS_LOG_FUNCTION(this);
279 return (m_address == 0xffffffffU);
280}
281
282bool
284{
285 //
286 // Multicast addresses are defined as ranging from 224.0.0.0 through
287 // 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
288 //
289 NS_LOG_FUNCTION(this);
290 return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
291}
292
293bool
295{
296 NS_LOG_FUNCTION(this);
297 // Link-Local multicast address is 224.0.0.0/24
298 return (m_address & 0xffffff00) == 0xe0000000;
299}
300
301void
302Ipv4Address::Serialize(uint8_t buf[4]) const
303{
304 NS_LOG_FUNCTION(this << &buf);
305 buf[0] = (m_address >> 24) & 0xff;
306 buf[1] = (m_address >> 16) & 0xff;
307 buf[2] = (m_address >> 8) & 0xff;
308 buf[3] = (m_address >> 0) & 0xff;
309}
310
312Ipv4Address::Deserialize(const uint8_t buf[4])
313{
314 NS_LOG_FUNCTION(&buf);
315 Ipv4Address ipv4;
316 ipv4.m_address = 0;
317 ipv4.m_address |= buf[0];
318 ipv4.m_address <<= 8;
319 ipv4.m_address |= buf[1];
320 ipv4.m_address <<= 8;
321 ipv4.m_address |= buf[2];
322 ipv4.m_address <<= 8;
323 ipv4.m_address |= buf[3];
324 ipv4.m_initialized = true;
325
326 return ipv4;
327}
328
329void
330Ipv4Address::Print(std::ostream& os) const
331{
332 NS_LOG_FUNCTION(this);
333 os << ((m_address >> 24) & 0xff) << "." << ((m_address >> 16) & 0xff) << "."
334 << ((m_address >> 8) & 0xff) << "." << ((m_address >> 0) & 0xff);
335}
336
337bool
339{
341 return address.CheckCompatible(GetType(), 4);
342}
343
344Ipv4Address::operator Address() const
345{
346 return ConvertTo();
347}
348
351{
352 NS_LOG_FUNCTION(this);
353 uint8_t buf[4];
354 Serialize(buf);
355 return Address(GetType(), buf, 4);
356}
357
360{
362 NS_ASSERT(address.CheckCompatible(GetType(), 4));
363 uint8_t buf[4];
364 address.CopyTo(buf);
365 return Deserialize(buf);
366}
367
368uint8_t
370{
372 static uint8_t type = Address::Register();
373 return type;
374}
375
378{
380 static Ipv4Address zero("0.0.0.0");
381 return zero;
382}
383
386{
388 static Ipv4Address any("0.0.0.0");
389 return any;
390}
391
394{
396 static Ipv4Address broadcast("255.255.255.255");
397 return broadcast;
398}
399
402{
404 Ipv4Address loopback("127.0.0.1");
405 return loopback;
406}
407
408size_t
410{
411 return std::hash<uint32_t>()(x.Get());
412}
413
414std::ostream&
415operator<<(std::ostream& os, const Ipv4Address& address)
416{
417 address.Print(os);
418 return os;
419}
420
421std::ostream&
422operator<<(std::ostream& os, const Ipv4Mask& mask)
423{
424 mask.Print(os);
425 return os;
426}
427
428std::istream&
429operator>>(std::istream& is, Ipv4Address& address)
430{
431 std::string str;
432 is >> str;
433 address = Ipv4Address(str.c_str());
434 return is;
435}
436
437std::istream&
438operator>>(std::istream& is, Ipv4Mask& mask)
439{
440 std::string str;
441 is >> str;
442 mask = Ipv4Mask(str.c_str());
443 return is;
444}
445
448
449} // namespace ns3
a polymophic address class
Definition: address.h:100
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:98
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:91
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
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 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 ",...
address
Definition: first.py:40
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:129
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
static constexpr uint32_t UNINITIALIZED
Value of a not-yet-initialized IPv4 address, corresponding to 102.102.102.102.