A Discrete-Event Network Simulator
API
ipv6-address.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2008 Louis Pasteur University
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: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 // Part of the Ipv6Address::Print function has been adapted from inet_ntop6 Linux function.
22 // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
23 // Author: Paul Vixie, 1996.
24 // The inet_ntop6 function was under the copyright below, which is
25 // compatible with GPLv2, see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses.
26 
27 /* Copyright (c) 1996 by Internet Software Consortium.
28  *
29  * Permission to use, copy, modify, and distribute this software for any
30  * purpose with or without fee is hereby granted, provided that the above
31  * copyright notice and this permission notice appear in all copies.
32  *
33  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
34  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
35  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
36  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
37  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
38  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
39  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
40  * SOFTWARE.
41  */
42 
43 
44 #include <iomanip>
45 #include <memory.h>
46 
47 #include "ns3/log.h"
48 #include "ns3/assert.h"
49 
50 #include "mac16-address.h"
51 #include "mac48-address.h"
52 #include "mac64-address.h"
53 #include "ipv6-address.h"
54 
55 namespace ns3 {
56 
57 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
58 
59 #ifdef __cplusplus
60 extern "C"
61 { /* } */
62 #endif
63 
72 static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
73 {
74  NS_LOG_FUNCTION (k << length << level);
75 #define mix(a, b, c) \
76  ({ \
77  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13); \
78  (b) -= (c); (b) -= (a); (b) ^= ((a) << 8); \
79  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13); \
80  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12); \
81  (b) -= (c); (b) -= (a); (b) ^= ((a) << 16); \
82  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5); \
83  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3); \
84  (b) -= (c); (b) -= (a); (b) ^= ((a) << 10); \
85  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15); \
86  })
87 
88  typedef uint32_t ub4; /* unsigned 4-byte quantities */
89  uint32_t a = 0;
90  uint32_t b = 0;
91  uint32_t c = 0;
92  uint32_t len = 0;
93 
94  /* Set up the internal state */
95  len = length;
96  a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
97  c = level; /* the previous hash value */
98 
99  /* handle most of the key */
100  while (len >= 12)
101  {
102  a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24));
103  b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24));
104  c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24));
105  mix (a, b, c);
106  k += 12;
107  len -= 12;
108  }
109 
110  /* handle the last 11 bytes */
111  c += length;
112  switch (len) /* all the case statements fall through */
113  {
114  case 11: c += ((ub4)k[10] << 24);
115  case 10: c += ((ub4)k[9] << 16);
116  case 9: c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */
117  case 8: b += ((ub4)k[7] << 24);
118  case 7: b += ((ub4)k[6] << 16);
119  case 6: b += ((ub4)k[5] << 8);
120  case 5: b += k[4];
121  case 4: a += ((ub4)k[3] << 24);
122  case 3: a += ((ub4)k[2] << 16);
123  case 2: a += ((ub4)k[1] << 8);
124  case 1: a += k[0];
125  /* case 0: nothing left to add */
126  }
127  mix (a, b, c);
128 
129 #undef mix
130 
131  /* report the result */
132  return c;
133 }
134 
135 #ifdef __cplusplus
136 }
137 #endif
138 
150 static bool AsciiToIpv6Host (const char *address, uint8_t addr[16])
151 {
152  NS_LOG_FUNCTION (address << &addr);
153  static const char xdigits_l[] = "0123456789abcdef";
154  static const char xdigits_u[] = "0123456789ABCDEF";
155  unsigned char tmp[16];
156  unsigned char* tp = tmp;
157  unsigned char* const endp = tp + 16;
158  unsigned char* colonp = 0;
159  const char* xdigits = 0;
160 #if 0
161  const char* curtok = 0;
162 #endif
163  int ch = 0;
164  int seen_xdigits = 0;
165  unsigned int val = 0;
166 
167  memset (tp, 0x00, 16);
168 
169  /* Leading :: requires some special handling. */
170  if (*address == ':')
171  {
172  if (*++address != ':')
173  {
174  return (0);
175  }
176  }
177 #if 0
178  curtok = address;
179 #endif
180  while ((ch = *address++) != '\0')
181  {
182  const char *pch = 0;
183 
184  if ((pch = strchr ((xdigits = xdigits_l), ch)) == 0)
185  {
186  pch = strchr ((xdigits = xdigits_u), ch);
187  }
188 
189  if (pch != 0)
190  {
191  val <<= 4;
192  val |= (pch - xdigits);
193 
194  if (++seen_xdigits > 4)
195  {
196  return (0);
197  }
198  continue;
199  }
200  if (ch == ':')
201  {
202 #if 0
203  curtok = address;
204 #endif
205 
206  if (!seen_xdigits)
207  {
208  if (colonp)
209  return (0);
210  colonp = tp;
211  continue;
212  }
213 
214  if (endp - tp < 2)
215  {
216  return (0);
217  }
218 
219  *tp++ = (unsigned char)(val >> 8) & 0xff;
220  *tp++ = (unsigned char) val & 0xff;
221  seen_xdigits = 0;
222  val = 0;
223  continue;
224  }
225 
226  /* \todo Handle IPv4 mapped address (2001::192.168.0.1) */
227 #if 0
228  if (ch == '.' && (endp - tp > 3 /* NS_INADDRSZ - 1 */)) &&
229  inet_pton4 (curtok, tp) > 0)
230  {
231  tp += 4 /*NS_INADDRSZ*/;
232  seen_xdigits = 0;
233  break; /* '\0' was seen by inet_pton4(). */
234  }
235 #endif
236  return (0);
237  }
238 
239  if (seen_xdigits)
240  {
241  if ( endp - tp < 2)
242  {
243  return (0);
244  }
245  *tp++ = (unsigned char)(val >> 8) & 0xff;
246  *tp++ = (unsigned char) val & 0xff;
247  }
248 
249  if (colonp != 0)
250  {
251  /*
252  * Since some memmove ()'s erroneously fail to handle
253  * overlapping regions, we'll do the shift by hand.
254  */
255  const int n = tp - colonp;
256  int i = 0;
257 
258  if (tp == endp)
259  {
260  return (0);
261  }
262 
263  for (i = 1; i <= n; i++)
264  {
265  endp[-i] = colonp[n - i];
266  colonp[n - i] = 0;
267  }
268 
269  tp = endp;
270  }
271 
272  if (tp != endp)
273  {
274  return (0);
275  }
276 
277  memcpy (addr, tmp, 16);
278  return (1);
279 }
280 
282 {
283  NS_LOG_FUNCTION (this);
284  memset (m_address, 0x00, 16);
285 }
286 
288 {
289  // Do not add function logging here, to avoid stack overflow
290  memcpy (m_address, addr.m_address, 16);
291 }
292 
294 {
295  // Do not add function logging here, to avoid stack overflow
296  memcpy (m_address, addr->m_address, 16);
297 }
298 
300 {
301  NS_LOG_FUNCTION (this << address);
302  AsciiToIpv6Host (address, m_address);
303 }
304 
306 {
307  NS_LOG_FUNCTION (this << &address);
308  /* 128 bit => 16 bytes */
309  memcpy (m_address, address, 16);
310 }
311 
313 {
314  /* do nothing */
315  NS_LOG_FUNCTION (this);
316 }
317 
318 void Ipv6Address::Set (char const* address)
319 {
320  NS_LOG_FUNCTION (this << address);
321  AsciiToIpv6Host (address, m_address);
322 }
323 
324 void Ipv6Address::Set (uint8_t address[16])
325 {
326  /* 128 bit => 16 bytes */
327  NS_LOG_FUNCTION (this << &address);
328  memcpy (m_address, address, 16);
329 }
330 
331 void Ipv6Address::Serialize (uint8_t buf[16]) const
332 {
333  NS_LOG_FUNCTION (this << &buf);
334  memcpy (buf, m_address, 16);
335 }
336 
337 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
338 {
339  NS_LOG_FUNCTION (&buf);
340  Ipv6Address ipv6 ((uint8_t*)buf);
341  return ipv6;
342 }
343 
345 {
346  NS_LOG_FUNCTION (addr);
347  uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
349  addr.Serialize (&buf[12]);
350  return (Ipv6Address (buf));
351 }
352 
354 {
355  NS_LOG_FUNCTION (this);
356  uint8_t buf[16];
357  Ipv4Address v4Addr;
358 
359  Serialize (buf);
360  v4Addr = Ipv4Address::Deserialize (&buf[12]);
361  return (v4Addr);
362 }
363 
365 {
366  NS_LOG_FUNCTION (addr << prefix);
367  Ipv6Address ret;
368  uint8_t buf[2];
369  uint8_t buf2[16];
370 
371  addr.CopyTo (buf);
372  prefix.GetBytes (buf2);
373 
374  memcpy (buf2 + 14, buf, 2);
375  buf2[11] = 0xff;
376  buf2[12] = 0xfe;
377 
378  ret.Set (buf2);
379  return ret;
380 }
381 
383 {
384  NS_LOG_FUNCTION (addr << prefix);
385  Ipv6Address ret;
386  uint8_t buf[16];
387  uint8_t buf2[16];
388 
389  addr.CopyTo (buf);
390  prefix.GetBytes (buf2);
391 
392  memcpy (buf2 + 8, buf, 3);
393  buf2[11] = 0xff;
394  buf2[12] = 0xfe;
395  memcpy (buf2 + 13, buf + 3, 3);
396  buf2[8] |= 0x02;
397 
398  ret.Set (buf2);
399  return ret;
400 }
401 
403 {
404  NS_LOG_FUNCTION (addr << prefix);
405  Ipv6Address ret;
406  uint8_t buf[8];
407  uint8_t buf2[16];
408 
409  addr.CopyTo (buf);
410  prefix.GetBytes (buf2);
411 
412  memcpy (buf2 + 8, buf, 8);
413 
414  ret.Set (buf2);
415  return ret;
416 }
417 
419 {
420  NS_LOG_FUNCTION (addr);
421  Ipv6Address ret;
422  uint8_t buf[2];
423  uint8_t buf2[16];
424 
425  addr.CopyTo (buf);
426 
427  memset (buf2, 0x00, sizeof (buf2));
428  buf2[0] = 0xfe;
429  buf2[1] = 0x80;
430  memcpy (buf2 + 14, buf, 2);
431  buf2[11] = 0xff;
432  buf2[12] = 0xfe;
433 
434  ret.Set (buf2);
435  return ret;
436 }
437 
439 {
440  NS_LOG_FUNCTION (addr);
441  Ipv6Address ret;
442  uint8_t buf[16];
443  uint8_t buf2[16];
444 
445  addr.CopyTo (buf);
446 
447  memset (buf2, 0x00, sizeof (buf2));
448  buf2[0] = 0xfe;
449  buf2[1] = 0x80;
450  memcpy (buf2 + 8, buf, 3);
451  buf2[11] = 0xff;
452  buf2[12] = 0xfe;
453  memcpy (buf2 + 13, buf + 3, 3);
454  buf2[8] |= 0x02;
455 
456  ret.Set (buf2);
457  return ret;
458 }
459 
461 {
462  NS_LOG_FUNCTION (addr);
463  Ipv6Address ret;
464  uint8_t buf[8];
465  uint8_t buf2[16];
466 
467  addr.CopyTo (buf);
468 
469  memset (buf2, 0x00, sizeof (buf2));
470  buf2[0] = 0xfe;
471  buf2[1] = 0x80;
472  memcpy (buf2 + 8, buf, 8);
473 
474  ret.Set (buf2);
475  return ret;
476 }
477 
479 {
480  NS_LOG_FUNCTION (addr);
481  uint8_t buf[16];
482  uint8_t buf2[16];
483  Ipv6Address ret;
484 
485  addr.Serialize (buf2);
486 
487  memset (buf, 0x00, sizeof (buf));
488  buf[0] = 0xff;
489  buf[1] = 0x02;
490  buf[11] = 0x01;
491  buf[12] = 0xff;
492  buf[13] = buf2[13];
493  buf[14] = buf2[14];
494  buf[15] = buf2[15];
495 
496  ret.Set (buf);
497  return ret;
498 }
499 
500 void Ipv6Address::Print (std::ostream& os) const
501 {
502  NS_LOG_FUNCTION (this << &os);
503 
504  // note: part of this function has been adapted from inet_ntop6 Linux function.
505  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
506  // Author: Paul Vixie, 1996.
507 
508  if (IsIpv4MappedAddress ())
509  {
510  os << "::ffff:"
511  << (unsigned int) m_address[12] << "."
512  << (unsigned int) m_address[13] << "."
513  << (unsigned int) m_address[14] << "."
514  << (unsigned int) m_address[15];
515  return;
516  }
517 
518  uint16_t address[8];
519  uint8_t i;
520 
521  for (i=0; i<8; i++)
522  {
523  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
524  }
525 
526  int8_t bestBase = -1;
527  int8_t bestLen = 0;
528  int8_t curBase = -1;
529  int8_t curLen = 0;
530 
531  for (i=0; i<8; i++)
532  {
533  if (address[i] == 0)
534  {
535  if (curBase == -1)
536  {
537  curBase = i;
538  curLen = 1;
539  }
540  else
541  {
542  curLen++;
543  }
544  }
545  else
546  {
547  if (curBase != -1)
548  {
549  if (bestBase == -1 || curLen > bestLen)
550  {
551  bestBase = curBase;
552  bestLen = curLen;
553  }
554  curBase = -1;
555  }
556  }
557  }
558  if (curBase != -1)
559  {
560  if (bestBase == -1 || curLen > bestLen)
561  {
562  bestBase = curBase;
563  bestLen = curLen;
564  }
565  }
566  if (bestBase != -1 && bestLen < 2)
567  {
568  bestBase = -1;
569  }
570 
571  for (i = 0; i < 8;) {
572  // Are we inside the best run of 0x00's?
573  if (i == bestBase)
574  {
575  os << ':';
576  i += bestLen;
577  continue;
578  }
579  // Are we following an initial run of 0x00s or any real hex?
580  if (i != 0)
581  {
582  os << ':';
583  }
584  os << std::hex << (unsigned int) address[i];
585  i++;
586  }
587  // Was it a trailing run of 0x00's?
588  if (bestBase != -1 && (bestBase + bestLen) == 8)
589  {
590  os << ':';
591  }
592  os << std::dec;
593 }
594 
596 {
597  NS_LOG_FUNCTION (this);
598  static Ipv6Address localhost ("::1");
599  return (*this == localhost);
600 }
601 
603 {
604  NS_LOG_FUNCTION (this);
605  if (m_address[0] == 0xff)
606  {
607  return true;
608  }
609  return false;
610 }
611 
613 {
614  NS_LOG_FUNCTION (this);
615  if (m_address[0] == 0xff && m_address[1] == 0x02)
616  {
617  return true;
618  }
619  return false;
620 }
621 
623 {
624  NS_LOG_FUNCTION (this);
625  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626  0x00, 0x00, 0xff, 0xff };
627  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
628  {
629  return (true);
630  }
631  return (false);
632 }
633 
635 {
636  NS_LOG_FUNCTION (this << prefix);
637  Ipv6Address ipv6;
638  uint8_t addr[16];
639  uint8_t pref[16];
640  unsigned int i = 0;
641 
642  memcpy (addr, m_address, 16);
643  ((Ipv6Prefix)prefix).GetBytes (pref);
644 
645  /* a little bit ugly... */
646  for (i = 0; i < 16; i++)
647  {
648  addr[i] = addr[i] & pref[i];
649  }
650  ipv6.Set (addr);
651  return ipv6;
652 }
653 
655 {
656  NS_LOG_FUNCTION (this);
657  uint8_t buf[16];
658 
659  Serialize (buf);
660 
661  if (buf[0] == 0xff &&
662  buf[1] == 0x02 &&
663  buf[11] == 0x01 &&
664  buf[12] == 0xff)
665  {
666  return true;
667  }
668  return false;
669 }
670 
672 {
673  NS_LOG_FUNCTION (this);
674  static Ipv6Address allNodesI ("ff01::1");
675  static Ipv6Address allNodesL ("ff02::1");
676  static Ipv6Address allNodesR ("ff03::1");
677  return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
678 }
679 
681 {
682  NS_LOG_FUNCTION (this);
683  static Ipv6Address allroutersI ("ff01::2");
684  static Ipv6Address allroutersL ("ff02::2");
685  static Ipv6Address allroutersR ("ff03::2");
686  static Ipv6Address allroutersS ("ff05::2");
687  return (*this == allroutersI || *this == allroutersL || *this == allroutersR || *this == allroutersS);
688 }
689 
691 {
692  NS_LOG_FUNCTION (this);
693  static Ipv6Address allhosts ("ff02::3");
694  return (*this == allhosts);
695 }
696 
697 bool Ipv6Address::IsAny () const
698 {
699  NS_LOG_FUNCTION (this);
700  static Ipv6Address any ("::");
701  return (*this == any);
702 }
703 
704 
706 {
707  NS_LOG_FUNCTION (this);
708  Ipv6Address documentation ("2001:db8::0");
709  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
710  {
711  return true;
712  }
713  return false;
714 }
715 
716 
718 {
719  NS_LOG_FUNCTION (address);
720  return address.CheckCompatible (GetType (), 16);
721 }
722 
723 Ipv6Address::operator Address () const
724 {
725  return ConvertTo ();
726 }
727 
729 {
730  NS_LOG_FUNCTION (this);
731  uint8_t buf[16];
732  Serialize (buf);
733  return Address (GetType (), buf, 16);
734 }
735 
737 {
738  NS_LOG_FUNCTION (address);
739  NS_ASSERT (address.CheckCompatible (GetType (), 16));
740  uint8_t buf[16];
741  address.CopyTo (buf);
742  return Deserialize (buf);
743 }
744 
745 uint8_t Ipv6Address::GetType (void)
746 {
748  static uint8_t type = Address::Register ();
749  return type;
750 }
751 
753 {
755  static Ipv6Address nmc ("ff02::1");
756  return nmc;
757 }
758 
760 {
762  static Ipv6Address rmc ("ff02::2");
763  return rmc;
764 }
765 
767 {
769  static Ipv6Address hmc ("ff02::3");
770  return hmc;
771 }
772 
774 {
776  static Ipv6Address loopback ("::1");
777  return loopback;
778 }
779 
781 {
783  static Ipv6Address zero ("::");
784  return zero;
785 }
786 
788 {
790  static Ipv6Address any ("::");
791  return any;
792 }
793 
795 {
797  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
798  return ones;
799 }
800 
801 void Ipv6Address::GetBytes (uint8_t buf[16]) const
802 {
803  NS_LOG_FUNCTION (this << &buf);
804  memcpy (buf, m_address, 16);
805 }
806 
808 {
809  NS_LOG_FUNCTION (this);
810  Ipv6Address linkLocal ("fe80::0");
811  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
812  {
813  return true;
814  }
815  return false;
816 }
817 
818 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
819 {
820  NS_LOG_FUNCTION (this << other);
821  if (!memcmp (m_address, other.m_address, 16))
822  {
823  return true;
824  }
825  return false;
826 }
827 
828 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
829 {
830  address.Print (os);
831  return os;
832 }
833 
834 std::istream& operator >> (std::istream& is, Ipv6Address& address)
835 {
836  std::string str;
837  is >> str;
838  address = Ipv6Address (str.c_str ());
839  return is;
840 }
841 
843 {
844  NS_LOG_FUNCTION (this);
845  memset (m_prefix, 0x00, 16);
846 }
847 
848 Ipv6Prefix::Ipv6Prefix (char const* prefix)
849 {
850  NS_LOG_FUNCTION (this << prefix);
851  AsciiToIpv6Host (prefix, m_prefix);
852 }
853 
854 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
855 {
856  NS_LOG_FUNCTION (this << &prefix);
857  memcpy (m_prefix, prefix, 16);
858 }
859 
860 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
861 {
862  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
863  unsigned int nb=0;
864  unsigned int mod=0;
865  unsigned int i=0;
866 
867  memset (m_prefix, 0x00, 16);
868 
869  NS_ASSERT (prefix <= 128);
870 
871  nb = prefix / 8;
872  mod = prefix % 8;
873 
874  // protect memset with 'nb > 0' check to suppress
875  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
876  if (nb > 0)
877  {
878  memset (m_prefix, 0xff, nb);
879  }
880  if (mod)
881  {
882  m_prefix[nb] = 0xff << (8-mod);
883  }
884 
885  if (nb < 16)
886  {
887  nb++;
888  for (i = nb; i < 16; i++)
889  {
890  m_prefix[i] = 0x00;
891  }
892  }
893 }
894 
896 {
897  memcpy (m_prefix, prefix.m_prefix, 16);
898 }
899 
901 {
902  memcpy (m_prefix, prefix->m_prefix, 16);
903 }
904 
906 {
907  /* do nothing */
908  NS_LOG_FUNCTION (this);
909 }
910 
912 {
913  NS_LOG_FUNCTION (this << a << b);
914  uint8_t addrA[16];
915  uint8_t addrB[16];
916  unsigned int i = 0;
917 
918  a.GetBytes (addrA);
919  b.GetBytes (addrB);
920 
921  /* a little bit ugly... */
922  for (i = 0; i < 16; i++)
923  {
924  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
925  {
926  return false;
927  }
928  }
929  return true;
930 }
931 
932 void Ipv6Prefix::Print (std::ostream &os) const
933 {
934  NS_LOG_FUNCTION (this << &os);
935 
936  os << "/" << (unsigned int) GetPrefixLength();
937 }
938 
940 {
942  static Ipv6Prefix prefix ((uint8_t)128);
943  return prefix;
944 }
945 
947 {
949  static Ipv6Prefix ones ((uint8_t)128);
950  return ones;
951 }
952 
954 {
956  static Ipv6Prefix prefix ((uint8_t)0);
957  return prefix;
958 }
959 
960 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
961 {
962  NS_LOG_FUNCTION (this << &buf);
963  memcpy (buf, m_prefix, 16);
964 }
965 
967 {
968  NS_LOG_FUNCTION (this);
969  uint8_t i = 0;
970  uint8_t prefixLength = 0;
971 
972  for(i = 0; i < 16; i++)
973  {
974  uint8_t mask = m_prefix[i];
975 
976  while(mask != 0)
977  {
978  mask = mask << 1;
979  prefixLength++;
980  }
981  }
982 
983  return prefixLength;
984 }
985 
986 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
987 {
988  if (!memcmp (m_prefix, other.m_prefix, 16))
989  {
990  return true;
991  }
992  return false;
993 }
994 
995 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
996 {
997  prefix.Print (os);
998  return os;
999 }
1000 
1001 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1002 {
1003  std::string str;
1004  is >> str;
1005  prefix = Ipv6Prefix (str.c_str ());
1006  return is;
1007 }
1008 
1010 {
1011  uint8_t buf[16];
1012 
1013  x.GetBytes (buf);
1014 
1015  return lookuphash (buf, sizeof (buf), 0);
1016 }
1017 
1020 
1021 } /* namespace ns3 */
1022 
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
bool IsAny() const
If the IPv6 address is the "Any" address.
static Ipv4Address Deserialize(const uint8_t buf[4])
static Ipv6Address GetLoopback()
Get the loopback address.
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv6Address()
Default constructor.
uint8_t m_address[16]
The address representation on 128 bits (16 bytes).
Definition: ipv6-address.h:357
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Ipv6Prefix()
Default constructor.
#define mix(a, b, c)
#define ATTRIBUTE_HELPER_CPP(type)
Define the attribute value, accessor and checkers for class type.
static Ipv6Address Deserialize(const uint8_t buf[16])
Deserialize this address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
~Ipv6Prefix()
Destructor.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool IsEqual(const Ipv6Prefix &other) const
Comparison operation between two Ipv6Prefix.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Mac16Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac16Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
size_t operator()(Ipv6Address const &x) const
Unary operator to hash IPv6 address.
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
NS_DEPRECATED bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
static double zero
static Ipv6Prefix GetZero()
Get the zero prefix ( /0).
static uint32_t lookuphash(unsigned char *k, uint32_t length, uint32_t level)
Get a hash key.
Definition: ipv6-address.cc:72
a polymophic address class
Definition: address.h:90
an EUI-64 address
Definition: mac64-address.h:43
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition: address.cc:122
void CopyTo(uint8_t buffer[8]) const
void CopyTo(uint8_t buffer[6]) const
Address ConvertTo(void) const
convert the IPv6Address object to an Address object.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
void CopyTo(uint8_t buffer[2]) const
void Print(std::ostream &os) const
Print this address to the given output stream.
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
void Set(char const *address)
Sets an Ipv6Address by parsing the input C-string.
static Ipv6Address GetAllHostsMulticast()
Get the "all hosts multicast" address.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
an EUI-48 address
Definition: mac48-address.h:43
uint8_t m_prefix[16]
The prefix representation.
Definition: ipv6-address.h:495
static bool AsciiToIpv6Host(const char *address, uint8_t addr[16])
Convert an IPv6 C-string into a 128-bit representation.
This class can contain 16 bit addresses.
Definition: mac16-address.h:41
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Mac16Address mac)
Make the autoconfigured link-local IPv6 address with Mac16Address.
Describes an IPv6 address.
Definition: ipv6-address.h:48
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void Print(std::ostream &os) const
Print this address to the given output stream.
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
~Ipv6Address()
Destructor.
static Ipv6Address GetOnes()
Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
static Ipv6Prefix GetLoopback()
Get the loopback prefix ( /128).
Describes an IPv6 prefix.
Definition: ipv6-address.h:394
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
uint8_t GetPrefixLength() const
Get prefix length.
tuple address
Definition: first.py:37
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
static uint8_t GetType(void)
Return the Type of address.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.