A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
ipv4-address.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2005 INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include <stdlib.h>
22 #include "ns3/log.h"
23 #include "ipv4-address.h"
24 #include "ns3/assert.h"
25 
26 NS_LOG_COMPONENT_DEFINE ("Ipv4Address");
27 
28 namespace ns3 {
29 
30 #define ASCII_DOT (0x2e)
31 #define ASCII_ZERO (0x30)
32 #define ASCII_SLASH (0x2f)
33 
34 static uint32_t
35 AsciiToIpv4Host (char const *address)
36 {
37  uint32_t host = 0;
38  while (true)
39  {
40  uint8_t byte = 0;
41  while (*address != ASCII_DOT && *address != 0)
42  {
43  byte *= 10;
44  byte += *address - ASCII_ZERO;
45  address++;
46  }
47  host <<= 8;
48  host |= byte;
49  if (*address == 0)
50  {
51  break;
52  }
53  address++;
54  }
55  return host;
56 }
57 
58 } // namespace ns3
59 
60 namespace ns3 {
61 
62 
64  : m_mask (0x66666666)
65 {
66 }
67 
68 Ipv4Mask::Ipv4Mask (uint32_t mask)
69  : m_mask (mask)
70 {
71 }
72 
73 Ipv4Mask::Ipv4Mask (char const *mask)
74 {
75  if (*mask == ASCII_SLASH)
76  {
77  uint32_t plen = static_cast<uint32_t> (atoi (++mask));
78  NS_ASSERT (plen <= 32);
79  if (plen > 0)
80  {
81  m_mask = 0xffffffff << (32 - plen);
82  }
83  else
84  {
85  m_mask = 0;
86  }
87  }
88  else
89  {
90  m_mask = AsciiToIpv4Host (mask);
91  }
92 }
93 
94 bool
96 {
97  if (other.m_mask == m_mask) {
98  return true;
99  } else {
100  return false;
101  }
102 }
103 
104 bool
106 {
107  if ((a.Get () & m_mask) == (b.Get () & m_mask)) {
108  return true;
109  } else {
110  return false;
111  }
112 }
113 
114 uint32_t
115 Ipv4Mask::Get (void) const
116 {
117  return m_mask;
118 }
119 void
120 Ipv4Mask::Set (uint32_t mask)
121 {
122  m_mask = mask;
123 }
124 uint32_t
126 {
127  return ~m_mask;
128 }
129 
130 void
131 Ipv4Mask::Print (std::ostream &os) const
132 {
133  os << ((m_mask >> 24) & 0xff) << "."
134  << ((m_mask >> 16) & 0xff) << "."
135  << ((m_mask >> 8) & 0xff) << "."
136  << ((m_mask >> 0) & 0xff);
137 }
138 
139 
140 Ipv4Mask
142 {
143  static Ipv4Mask loopback = Ipv4Mask ("255.0.0.0");
144  return loopback;
145 }
146 Ipv4Mask
148 {
149  static Ipv4Mask zero = Ipv4Mask ("0.0.0.0");
150  return zero;
151 }
152 Ipv4Mask
154 {
155  static Ipv4Mask ones = Ipv4Mask ("255.255.255.255");
156  return ones;
157 }
158 
159 uint16_t
161 {
162  uint16_t tmp = 0;
163  uint32_t mask = m_mask;
164  while (mask != 0 )
165  {
166  mask = mask << 1;
167  tmp++;
168  }
169  return tmp;
170 }
171 
172 
174  : m_address (0x66666666)
175 {
176 }
177 Ipv4Address::Ipv4Address (uint32_t address)
178 {
179  m_address = address;
180 }
181 Ipv4Address::Ipv4Address (char const *address)
182 {
183  m_address = AsciiToIpv4Host (address);
184 }
185 
186 uint32_t
187 Ipv4Address::Get (void) const
188 {
189  return m_address;
190 }
191 void
192 Ipv4Address::Set (uint32_t address)
193 {
194  m_address = address;
195 }
196 void
197 Ipv4Address::Set (char const *address)
198 {
199  m_address = AsciiToIpv4Host (address);
200 }
201 
204 {
205  return Ipv4Address (Get () & mask.Get ());
206 }
207 
210 {
211  if (mask == Ipv4Mask::GetOnes ())
212  {
213  NS_ASSERT_MSG (false, "Trying to get subnet-directed broadcast address with an all-ones netmask");
214  }
215  return Ipv4Address (Get () | mask.GetInverse ());
216 }
217 
218 bool
220 {
221  if (mask == Ipv4Mask::GetOnes ())
222  {
223  // If the mask is 255.255.255.255, there is no subnet directed
224  // broadcast for this address.
225  return false;
226  }
227  return ( (Get () | mask.GetInverse ()) == Get () );
228 }
229 
230 bool
232 {
233  return (m_address == 0xffffffffU);
234 }
235 
236 bool
238 {
239 //
240 // Multicast addresses are defined as ranging from 224.0.0.0 through
241 // 239.255.255.255 (which is E0000000 through EFFFFFFF in hex).
242 //
243  return (m_address >= 0xe0000000 && m_address <= 0xefffffff);
244 }
245 
246 bool
248 {
249  // Link-Local multicast address is 224.0.0.0/24
250  return (m_address & 0xffffff00) == 0xe0000000;
251 }
252 
253 void
254 Ipv4Address::Serialize (uint8_t buf[4]) const
255 {
256  buf[0] = (m_address >> 24) & 0xff;
257  buf[1] = (m_address >> 16) & 0xff;
258  buf[2] = (m_address >> 8) & 0xff;
259  buf[3] = (m_address >> 0) & 0xff;
260 }
262 Ipv4Address::Deserialize (const uint8_t buf[4])
263 {
264  Ipv4Address ipv4;
265  ipv4.m_address = 0;
266  ipv4.m_address |= buf[0];
267  ipv4.m_address <<= 8;
268  ipv4.m_address |= buf[1];
269  ipv4.m_address <<= 8;
270  ipv4.m_address |= buf[2];
271  ipv4.m_address <<= 8;
272  ipv4.m_address |= buf[3];
273  return ipv4;
274 }
275 
276 void
277 Ipv4Address::Print (std::ostream &os) const
278 {
279  os << ((m_address >> 24) & 0xff) << "."
280  << ((m_address >> 16) & 0xff) << "."
281  << ((m_address >> 8) & 0xff) << "."
282  << ((m_address >> 0) & 0xff);
283 }
284 
285 bool
287 {
288  return address.CheckCompatible (GetType (), 4);
289 }
290 Ipv4Address::operator Address () const
291 {
292  return ConvertTo ();
293 }
294 
295 Address
297 {
298  uint8_t buf[4];
299  Serialize (buf);
300  return Address (GetType (), buf, 4);
301 }
302 
305 {
306  NS_ASSERT (address.CheckCompatible (GetType (), 4));
307  uint8_t buf[4];
308  address.CopyTo (buf);
309  return Deserialize (buf);
310 }
311 
312 uint8_t
314 {
315  static uint8_t type = Address::Register ();
316  return type;
317 }
318 
321 {
322  static Ipv4Address zero ("0.0.0.0");
323  return zero;
324 }
327 {
328  static Ipv4Address any ("0.0.0.0");
329  return any;
330 }
333 {
334  static Ipv4Address broadcast ("255.255.255.255");
335  return broadcast;
336 }
339 {
340  Ipv4Address loopback ("127.0.0.1");
341  return loopback;
342 }
343 
345 {
346  return x.Get ();
347 }
348 
349 std::ostream& operator<< (std::ostream& os, Ipv4Address const& address)
350 {
351  address.Print (os);
352  return os;
353 }
354 std::ostream& operator<< (std::ostream& os, Ipv4Mask const& mask)
355 {
356  mask.Print (os);
357  return os;
358 }
359 std::istream & operator >> (std::istream &is, Ipv4Address &address)
360 {
361  std::string str;
362  is >> str;
363  address = Ipv4Address (str.c_str ());
364  return is;
365 }
366 std::istream & operator >> (std::istream &is, Ipv4Mask &mask)
367 {
368  std::string str;
369  is >> str;
370  mask = Ipv4Mask (str.c_str ());
371  return is;
372 }
373 
374 bool operator == (Ipv4Mask const &a, Ipv4Mask const &b)
375 {
376  return a.IsEqual (b);
377 }
378 bool operator != (Ipv4Mask const &a, Ipv4Mask const &b)
379 {
380  return !a.IsEqual (b);
381 }
382 
383 ATTRIBUTE_HELPER_CPP (Ipv4Address);
384 ATTRIBUTE_HELPER_CPP (Ipv4Mask);
385 
386 } // namespace ns3