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 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("Ipv4Address");
37 
39  : m_mask(0x66666666)
40 {
41  NS_LOG_FUNCTION(this);
42 }
43 
44 Ipv4Mask::Ipv4Mask(uint32_t mask)
45  : m_mask(mask)
46 {
47  NS_LOG_FUNCTION(this << mask);
48 }
49 
50 Ipv4Mask::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 
76 bool
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 
90 uint32_t
92 {
93  NS_LOG_FUNCTION(this);
94  return m_mask;
95 }
96 
97 void
98 Ipv4Mask::Set(uint32_t mask)
99 {
100  NS_LOG_FUNCTION(this << mask);
101  m_mask = mask;
102 }
103 
104 uint32_t
106 {
107  NS_LOG_FUNCTION(this);
108  return ~m_mask;
109 }
110 
111 void
112 Ipv4Mask::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 
119 Ipv4Mask
121 {
123  static Ipv4Mask loopback = Ipv4Mask("255.0.0.0");
124  return loopback;
125 }
126 
127 Ipv4Mask
129 {
131  static Ipv4Mask zero = Ipv4Mask("0.0.0.0");
132  return zero;
133 }
134 
135 Ipv4Mask
137 {
139  static Ipv4Mask ones = Ipv4Mask("255.255.255.255");
140  return ones;
141 }
142 
143 uint16_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 
161 static 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);
173  m_address = 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 
192 uint32_t
194 {
195  NS_LOG_FUNCTION(this);
196  return m_address;
197 }
198 
199 void
201 {
202  NS_LOG_FUNCTION(this << address);
203  m_address = address;
204  m_initialized = true;
205 }
206 
207 void
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 
241 bool
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 
254 bool
256 {
257  NS_LOG_FUNCTION(this);
258  return (m_initialized);
259 }
260 
261 bool
263 {
264  NS_LOG_FUNCTION(this);
265  return (m_address == 0x00000000U);
266 }
267 
268 bool
270 {
271  NS_LOG_FUNCTION(this);
272  return (m_address == 0x7f000001U);
273 }
274 
275 bool
277 {
278  NS_LOG_FUNCTION(this);
279  return (m_address == 0xffffffffU);
280 }
281 
282 bool
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 
293 bool
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 
301 void
302 Ipv4Address::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 
312 Ipv4Address::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 
329 void
330 Ipv4Address::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 
337 bool
339 {
341  return address.CheckCompatible(GetType(), 4);
342 }
343 
344 Ipv4Address::operator Address() const
345 {
346  return ConvertTo();
347 }
348 
349 Address
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 
368 uint8_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 
408 size_t
410 {
411  return std::hash<uint32_t>()(x.Get());
412 }
413 
414 std::ostream&
415 operator<<(std::ostream& os, const Ipv4Address& address)
416 {
417  address.Print(os);
418  return os;
419 }
420 
421 std::ostream&
422 operator<<(std::ostream& os, const Ipv4Mask& mask)
423 {
424  mask.Print(os);
425  return os;
426 }
427 
428 std::istream&
429 operator>>(std::istream& is, Ipv4Address& address)
430 {
431  std::string str;
432  is >> str;
433  address = Ipv4Address(str.c_str());
434  return is;
435 }
436 
437 std::istream&
438 operator>>(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:43
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:216
uint32_t m_address
IPv4 address.
Definition: ipv4-address.h:215
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:258
uint32_t m_mask
IP mask.
Definition: ipv4-address.h:339
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.
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:129
static constexpr uint32_t UNINITIALIZED
Value of a not-yet-initialized IPv4 address, corresponding to 102.102.102.102.