A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 #include <iomanip>
22 #include <memory.h>
23 
24 #include "ns3/log.h"
25 #include "ns3/assert.h"
26 
27 #include "mac16-address.h"
28 #include "mac48-address.h"
29 #include "mac64-address.h"
30 #include "ipv6-address.h"
31 
32 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
33 
34 namespace ns3 {
35 
36 #ifdef __cplusplus
37 extern "C"
38 { /* } */
39 #endif
40 
49 static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
50 {
51  NS_LOG_FUNCTION (k << length << level);
52 #define mix(a, b, c) \
53  ({ \
54  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13); \
55  (b) -= (c); (b) -= (a); (b) ^= ((a) << 8); \
56  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13); \
57  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12); \
58  (b) -= (c); (b) -= (a); (b) ^= ((a) << 16); \
59  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5); \
60  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3); \
61  (b) -= (c); (b) -= (a); (b) ^= ((a) << 10); \
62  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15); \
63  })
64 
65  typedef uint32_t ub4; /* unsigned 4-byte quantities */
66  uint32_t a = 0;
67  uint32_t b = 0;
68  uint32_t c = 0;
69  uint32_t len = 0;
70 
71  /* Set up the internal state */
72  len = length;
73  a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
74  c = level; /* the previous hash value */
75 
76  /* handle most of the key */
77  while (len >= 12)
78  {
79  a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24));
80  b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24));
81  c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24));
82  mix (a, b, c);
83  k += 12;
84  len -= 12;
85  }
86 
87  /* handle the last 11 bytes */
88  c += length;
89  switch (len) /* all the case statements fall through */
90  {
91  case 11: c += ((ub4)k[10] << 24);
92  case 10: c += ((ub4)k[9] << 16);
93  case 9: c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */
94  case 8: b += ((ub4)k[7] << 24);
95  case 7: b += ((ub4)k[6] << 16);
96  case 6: b += ((ub4)k[5] << 8);
97  case 5: b += k[4];
98  case 4: a += ((ub4)k[3] << 24);
99  case 3: a += ((ub4)k[2] << 16);
100  case 2: a += ((ub4)k[1] << 8);
101  case 1: a += k[0];
102  /* case 0: nothing left to add */
103  }
104  mix (a, b, c);
105 
106 #undef mix
107 
108  /* report the result */
109  return c;
110 }
111 
112 #ifdef __cplusplus
113 }
114 #endif
115 
122 static bool AsciiToIpv6Host (const char *address, uint8_t addr[16])
123 {
124  NS_LOG_FUNCTION (address << &addr);
125  static const char xdigits_l[] = "0123456789abcdef";
126  static const char xdigits_u[] = "0123456789ABCDEF";
127  unsigned char tmp[16];
128  unsigned char* tp = tmp;
129  unsigned char* endp = 0;
130  unsigned char* colonp = 0;
131  const char* xdigits = 0;
132 #if 0
133  const char* curtok = 0;
134 #endif
135  int ch = 0;
136  int seen_xdigits = 0;
137  unsigned int val = 0;
138 
139  memset (tp, 0x00, 16);
140  endp = tp + 16;
141 
142  /* Leading :: requires some special handling. */
143  if (*address == ':')
144  {
145  if (*++address != ':')
146  {
147  return (0);
148  }
149  }
150 #if 0
151  curtok = address;
152 #endif
153  while ((ch = *address++) != '\0')
154  {
155  const char *pch = 0;
156 
157  if ((pch = strchr ((xdigits = xdigits_l), ch)) == 0)
158  {
159  pch = strchr ((xdigits = xdigits_u), ch);
160  }
161 
162  if (pch != 0)
163  {
164  val <<= 4;
165  val |= (pch - xdigits);
166 
167  if (++seen_xdigits > 4)
168  {
169  return (0);
170  }
171  continue;
172  }
173  if (ch == ':')
174  {
175 #if 0
176  curtok = address;
177 #endif
178 
179  if (!seen_xdigits)
180  {
181  if (colonp)
182  return (0);
183  colonp = tp;
184  continue;
185  }
186 
187  if (tp + 2 > endp)
188  {
189  return (0);
190  }
191 
192  *tp++ = (unsigned char)(val >> 8) & 0xff;
193  *tp++ = (unsigned char) val & 0xff;
194  seen_xdigits = 0;
195  val = 0;
196  continue;
197  }
198 
199  /* \todo Handle IPv4 mapped address (2001::192.168.0.1) */
200 #if 0
201  if (ch == '.' && ((tp + 4 /*NS_INADDRSZ*/) <= endp) &&
202  inet_pton4 (curtok, tp) > 0)
203  {
204  tp += 4 /*NS_INADDRSZ*/;
205  seen_xdigits = 0;
206  break; /* '\0' was seen by inet_pton4(). */
207  }
208 #endif
209  return (0);
210  }
211 
212  if (seen_xdigits)
213  {
214  if (tp + 2 > endp)
215  {
216  return (0);
217  }
218  *tp++ = (unsigned char)(val >> 8) & 0xff;
219  *tp++ = (unsigned char) val & 0xff;
220  }
221 
222  if (colonp != 0)
223  {
224  /*
225  * Since some memmove ()'s erroneously fail to handle
226  * overlapping regions, we'll do the shift by hand.
227  */
228  const int n = tp - colonp;
229  int i = 0;
230 
231  if (tp == endp)
232  {
233  return (0);
234  }
235 
236  for (i = 1; i <= n; i++)
237  {
238  endp[-i] = colonp[n - i];
239  colonp[n - i] = 0;
240  }
241 
242  tp = endp;
243  }
244 
245  if (tp != endp)
246  {
247  return (0);
248  }
249 
250  memcpy (addr, tmp, 16);
251  return (1);
252 }
253 
255 {
256  NS_LOG_FUNCTION (this);
257  memset (m_address, 0x00, 16);
258 }
259 
261 {
262  // Do not add function logging here, to avoid stack overflow
263  memcpy (m_address, addr.m_address, 16);
264 }
265 
267 {
268  // Do not add function logging here, to avoid stack overflow
269  memcpy (m_address, addr->m_address, 16);
270 }
271 
273 {
274  NS_LOG_FUNCTION (this << address);
275  AsciiToIpv6Host (address, m_address);
276 }
277 
279 {
280  NS_LOG_FUNCTION (this << &address);
281  /* 128 bit => 16 bytes */
282  memcpy (m_address, address, 16);
283 }
284 
286 {
287  /* do nothing */
288  NS_LOG_FUNCTION (this);
289 }
290 
291 void Ipv6Address::Set (char const* address)
292 {
293  NS_LOG_FUNCTION (this << address);
294  AsciiToIpv6Host (address, m_address);
295 }
296 
297 void Ipv6Address::Set (uint8_t address[16])
298 {
299  /* 128 bit => 16 bytes */
300  NS_LOG_FUNCTION (this << &address);
301  memcpy (m_address, address, 16);
302 }
303 
304 void Ipv6Address::Serialize (uint8_t buf[16]) const
305 {
306  NS_LOG_FUNCTION (this << &buf);
307  memcpy (buf, m_address, 16);
308 }
309 
310 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
311 {
312  NS_LOG_FUNCTION (&buf);
313  Ipv6Address ipv6 ((uint8_t*)buf);
314  return ipv6;
315 }
316 
318 {
319  NS_LOG_FUNCTION (addr);
320  uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
321  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
322  addr.Serialize (&buf[12]);
323  return (Ipv6Address (buf));
324 }
325 
327 {
328  NS_LOG_FUNCTION (this);
329  uint8_t buf[16];
330  Ipv4Address v4Addr;
331 
332  Serialize (buf);
333  v4Addr = Ipv4Address::Deserialize (&buf[12]);
334  return (v4Addr);
335 }
336 
338 {
339  NS_LOG_FUNCTION (addr << prefix);
340  Ipv6Address ret;
341  uint8_t buf[2];
342  uint8_t buf2[16];
343 
344  addr.CopyTo (buf);
345  prefix.GetBytes (buf2);
346 
347  memcpy (buf2 + 14, buf, 2);
348  buf2[11] = 0xff;
349  buf2[12] = 0xfe;
350 
351  ret.Set (buf2);
352  return ret;
353 }
354 
356 {
357  NS_LOG_FUNCTION (addr << prefix);
358  Ipv6Address ret;
359  uint8_t buf[16];
360  uint8_t buf2[16];
361 
362  addr.CopyTo (buf);
363  prefix.GetBytes (buf2);
364 
365  memcpy (buf2 + 8, buf, 3);
366  buf2[11] = 0xff;
367  buf2[12] = 0xfe;
368  memcpy (buf2 + 13, buf + 3, 3);
369  buf2[8] |= 0x02;
370 
371  ret.Set (buf2);
372  return ret;
373 }
374 
376 {
377  NS_LOG_FUNCTION (addr << prefix);
378  Ipv6Address ret;
379  uint8_t buf[8];
380  uint8_t buf2[16];
381 
382  addr.CopyTo (buf);
383  prefix.GetBytes (buf2);
384 
385  memcpy (buf2 + 8, buf, 8);
386 
387  ret.Set (buf2);
388  return ret;
389 }
390 
392 {
393  NS_LOG_FUNCTION (addr);
394  Ipv6Address ret;
395  uint8_t buf[2];
396  uint8_t buf2[16];
397 
398  addr.CopyTo (buf);
399 
400  memset (buf2, 0x00, sizeof (buf2));
401  buf2[0] = 0xfe;
402  buf2[1] = 0x80;
403  memcpy (buf2 + 14, buf, 2);
404  buf2[11] = 0xff;
405  buf2[12] = 0xfe;
406 
407  ret.Set (buf2);
408  return ret;
409 }
410 
412 {
413  NS_LOG_FUNCTION (addr);
414  Ipv6Address ret;
415  uint8_t buf[16];
416  uint8_t buf2[16];
417 
418  addr.CopyTo (buf);
419 
420  memset (buf2, 0x00, sizeof (buf2));
421  buf2[0] = 0xfe;
422  buf2[1] = 0x80;
423  memcpy (buf2 + 8, buf, 3);
424  buf2[11] = 0xff;
425  buf2[12] = 0xfe;
426  memcpy (buf2 + 13, buf + 3, 3);
427  buf2[8] |= 0x02;
428 
429  ret.Set (buf2);
430  return ret;
431 }
432 
434 {
435  NS_LOG_FUNCTION (addr);
436  Ipv6Address ret;
437  uint8_t buf[8];
438  uint8_t buf2[16];
439 
440  addr.CopyTo (buf);
441 
442  memset (buf2, 0x00, sizeof (buf2));
443  buf2[0] = 0xfe;
444  buf2[1] = 0x80;
445  memcpy (buf2 + 8, buf, 8);
446 
447  ret.Set (buf2);
448  return ret;
449 }
450 
452 {
453  NS_LOG_FUNCTION (addr);
454  uint8_t buf[16];
455  uint8_t buf2[16];
456  Ipv6Address ret;
457 
458  addr.Serialize (buf2);
459 
460  memset (buf, 0x00, sizeof (buf));
461  buf[0] = 0xff;
462  buf[1] = 0x02;
463  buf[11] = 0x01;
464  buf[12] = 0xff;
465  buf[13] = buf2[13];
466  buf[14] = buf2[14];
467  buf[15] = buf2[15];
468 
469  ret.Set (buf);
470  return ret;
471 }
472 
473 void Ipv6Address::Print (std::ostream& os) const
474 {
475  NS_LOG_FUNCTION (this << &os);
476  os << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[0]
477  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[1] << ":"
478  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[2]
479  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[3] << ":"
480  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[4]
481  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[5] << ":"
482  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[6]
483  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[7] << ":"
484  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[8]
485  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[9] << ":"
486  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[10]
487  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[11] << ":"
488  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[12]
489  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[13] << ":"
490  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[14]
491  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_address[15]
492  << std::dec << std::setfill (' ');
493 }
494 
496 {
497  NS_LOG_FUNCTION (this);
498  static Ipv6Address localhost ("::1");
499  return (*this == localhost);
500 }
501 
503 {
504  NS_LOG_FUNCTION (this);
505  if (m_address[0] == 0xff)
506  {
507  return true;
508  }
509  return false;
510 }
511 
513 {
514  NS_LOG_FUNCTION (this);
515  if (m_address[0] == 0xff && m_address[1] == 0x02)
516  {
517  return true;
518  }
519  return false;
520 }
521 
523 {
524  NS_LOG_FUNCTION (this);
525  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526  0x00, 0x00, 0xff, 0xff };
527  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
528  {
529  return (true);
530  }
531  return (false);
532 }
533 
535 {
536  NS_LOG_FUNCTION (this << prefix);
537  Ipv6Address ipv6;
538  uint8_t addr[16];
539  uint8_t pref[16];
540  unsigned int i = 0;
541 
542  memcpy (addr, m_address, 16);
543  ((Ipv6Prefix)prefix).GetBytes (pref);
544 
545  /* a little bit ugly... */
546  for (i = 0; i < 16; i++)
547  {
548  addr[i] = addr[i] & pref[i];
549  }
550  ipv6.Set (addr);
551  return ipv6;
552 }
553 
555 {
556  NS_LOG_FUNCTION (this);
557  uint8_t buf[16];
558 
559  Serialize (buf);
560 
561  if (buf[0] == 0xff &&
562  buf[1] == 0x02 &&
563  buf[11] == 0x01 &&
564  buf[12] == 0xff)
565  {
566  return true;
567  }
568  return false;
569 }
570 
572 {
573  NS_LOG_FUNCTION (this);
574  static Ipv6Address allnodes ("ff02::1");
575  return (*this == allnodes);
576 }
577 
579 {
580  NS_LOG_FUNCTION (this);
581  static Ipv6Address allrouters ("ff02::2");
582  return (*this == allrouters);
583 }
584 
586 {
587  NS_LOG_FUNCTION (this);
588  static Ipv6Address allhosts ("ff02::3");
589  return (*this == allhosts);
590 }
591 
592 bool Ipv6Address::IsAny () const
593 {
594  NS_LOG_FUNCTION (this);
595  static Ipv6Address any ("::");
596  return (*this == any);
597 }
598 
599 
601 {
602  NS_LOG_FUNCTION (this);
603  Ipv6Address documentation ("2001:db8::0");
604  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
605  {
606  return true;
607  }
608  return false;
609 }
610 
611 
613 {
614  NS_LOG_FUNCTION (address);
615  return address.CheckCompatible (GetType (), 16);
616 }
617 
618 Ipv6Address::operator Address () const
619 {
620  return ConvertTo ();
621 }
622 
624 {
625  NS_LOG_FUNCTION (this);
626  uint8_t buf[16];
627  Serialize (buf);
628  return Address (GetType (), buf, 16);
629 }
630 
632 {
633  NS_LOG_FUNCTION (address);
634  NS_ASSERT (address.CheckCompatible (GetType (), 16));
635  uint8_t buf[16];
636  address.CopyTo (buf);
637  return Deserialize (buf);
638 }
639 
640 uint8_t Ipv6Address::GetType (void)
641 {
643  static uint8_t type = Address::Register ();
644  return type;
645 }
646 
648 {
650  static Ipv6Address nmc ("ff02::1");
651  return nmc;
652 }
653 
655 {
657  static Ipv6Address rmc ("ff02::2");
658  return rmc;
659 }
660 
662 {
664  static Ipv6Address hmc ("ff02::3");
665  return hmc;
666 }
667 
669 {
671  static Ipv6Address loopback ("::1");
672  return loopback;
673 }
674 
676 {
678  static Ipv6Address zero ("::");
679  return zero;
680 }
681 
683 {
685  static Ipv6Address any ("::");
686  return any;
687 }
688 
690 {
692  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
693  return ones;
694 }
695 
696 void Ipv6Address::GetBytes (uint8_t buf[16]) const
697 {
698  NS_LOG_FUNCTION (this << &buf);
699  memcpy (buf, m_address, 16);
700 }
701 
703 {
704  NS_LOG_FUNCTION (this);
705  Ipv6Address linkLocal ("fe80::0");
706  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
707  {
708  return true;
709  }
710  return false;
711 }
712 
713 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
714 {
715  NS_LOG_FUNCTION (this << other);
716  if (!memcmp (m_address, other.m_address, 16))
717  {
718  return true;
719  }
720  return false;
721 }
722 
723 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
724 {
725  address.Print (os);
726  return os;
727 }
728 
729 std::istream& operator >> (std::istream& is, Ipv6Address& address)
730 {
731  std::string str;
732  is >> str;
733  address = Ipv6Address (str.c_str ());
734  return is;
735 }
736 
738 {
739  NS_LOG_FUNCTION (this);
740  memset (m_prefix, 0x00, 16);
741 }
742 
743 Ipv6Prefix::Ipv6Prefix (char const* prefix)
744 {
745  NS_LOG_FUNCTION (this << prefix);
746  AsciiToIpv6Host (prefix, m_prefix);
747 }
748 
749 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
750 {
751  NS_LOG_FUNCTION (this << &prefix);
752  memcpy (m_prefix, prefix, 16);
753 }
754 
755 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
756 {
757  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
758  unsigned int nb=0;
759  unsigned int mod=0;
760  unsigned int i=0;
761 
762  memset (m_prefix, 0x00, 16);
763 
764  NS_ASSERT (prefix <= 128);
765 
766  nb = prefix / 8;
767  mod = prefix % 8;
768 
769  // protect memset with 'nb > 0' check to suppress
770  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
771  if (nb > 0)
772  {
773  memset (m_prefix, 0xff, nb);
774  }
775  if (mod)
776  {
777  m_prefix[nb] = 0xff << (8-mod);
778  }
779 
780  if (nb < 16)
781  {
782  nb++;
783  for (i = nb; i < 16; i++)
784  {
785  m_prefix[i] = 0x00;
786  }
787  }
788 }
789 
791 {
792  memcpy (m_prefix, prefix.m_prefix, 16);
793 }
794 
796 {
797  memcpy (m_prefix, prefix->m_prefix, 16);
798 }
799 
801 {
802  /* do nothing */
803  NS_LOG_FUNCTION (this);
804 }
805 
807 {
808  NS_LOG_FUNCTION (this << a << b);
809  uint8_t addrA[16];
810  uint8_t addrB[16];
811  unsigned int i = 0;
812 
813  a.GetBytes (addrA);
814  b.GetBytes (addrB);
815 
816  /* a little bit ugly... */
817  for (i = 0; i < 16; i++)
818  {
819  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
820  {
821  return false;
822  }
823  }
824  return true;
825 }
826 
827 void Ipv6Prefix::Print (std::ostream &os) const
828 {
829  NS_LOG_FUNCTION (this << &os);
830  os << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[0]
831  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[1] << ":"
832  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[2]
833  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[3] << ":"
834  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[4]
835  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[5] << ":"
836  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[6]
837  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[7] << ":"
838  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[8]
839  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[9] << ":"
840  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[10]
841  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[11] << ":"
842  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[12]
843  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[13] << ":"
844  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[14]
845  << std::hex << std::setw (2) << std::setfill ('0') << (unsigned int) m_prefix[15];
846 }
847 
849 {
851  static Ipv6Prefix prefix ((uint8_t)128);
852  return prefix;
853 }
854 
856 {
858  static Ipv6Prefix ones ((uint8_t)128);
859  return ones;
860 }
861 
863 {
865  static Ipv6Prefix prefix ((uint8_t)0);
866  return prefix;
867 }
868 
869 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
870 {
871  NS_LOG_FUNCTION (this << &buf);
872  memcpy (buf, m_prefix, 16);
873 }
874 
876 {
877  NS_LOG_FUNCTION (this);
878  uint8_t i = 0;
879  uint8_t prefixLength = 0;
880 
881  for(i = 0; i < 16; i++)
882  {
883  uint8_t mask = m_prefix[i];
884 
885  while(mask != 0)
886  {
887  mask = mask << 1;
888  prefixLength++;
889  }
890  }
891 
892  return prefixLength;
893 }
894 
895 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
896 {
897  if (!memcmp (m_prefix, other.m_prefix, 16))
898  {
899  return true;
900  }
901  return false;
902 }
903 
904 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
905 {
906  prefix.Print (os);
907  return os;
908 }
909 
910 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
911 {
912  std::string str;
913  is >> str;
914  prefix = Ipv6Prefix (str.c_str ());
915  return is;
916 }
917 
918 bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b)
919 {
920  return a.IsEqual (b);
921 }
922 
923 bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b)
924 {
925  return !a.IsEqual (b);
926 }
927 
929 {
930  uint8_t buf[16];
931 
932  x.GetBytes (buf);
933 
934  return lookuphash (buf, sizeof (buf), 0);
935 }
936 
939 
940 } /* namespace ns3 */
941 
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)
Definition: angles.cc:49
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
Ipv6Address()
Default constructor.
uint8_t m_address[16]
The address representation on 128 bits (16 bytes).
Definition: ipv6-address.h:351
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Ipv6Prefix()
Default constructor.
#define mix(a, b, c)
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)
Definition: assert.h:64
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.
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).
bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
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:49
a polymophic address class
Definition: address.h:86
an EUI-64 address
Definition: mac64-address.h:41
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
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)
Definition: angles.cc:43
bool operator!=(Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > a, Callback< R, T1, T2, T3, T4, T5, T6, T7, T8, T9 > b)
Definition: callback.h:1213
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:41
uint8_t m_prefix[16]
The prefix representation.
Definition: ipv6-address.h:465
static bool AsciiToIpv6Host(const char *address, uint8_t addr[16])
Convert an IPv6 C-string into a 128-bit representation.
NS_LOG_COMPONENT_DEFINE("Ipv6Address")
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Mac16Address mac)
Make the autoconfigured link-local IPv6 address with Mac16Address.
Describes an IPv6 address.
Definition: ipv6-address.h:46
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
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
Definition: address.cc:82
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
bool operator==(const EventId &a, const EventId &b)
Definition: event-id.cc:89
~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. It is just a bitmask like Ipv4Mask.
Definition: ipv6-address.h:364
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
uint8_t GetPrefixLength() const
Get prefix length.
tuple address
Definition: first.py:37
ATTRIBUTE_HELPER_CPP(ObjectFactory)
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()
If the address is an IPv4-mapped address.
static uint8_t Register(void)
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.