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 // 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 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
56 
57 namespace ns3 {
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* endp = 0;
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  endp = tp + 16;
169 
170  /* Leading :: requires some special handling. */
171  if (*address == ':')
172  {
173  if (*++address != ':')
174  {
175  return (0);
176  }
177  }
178 #if 0
179  curtok = address;
180 #endif
181  while ((ch = *address++) != '\0')
182  {
183  const char *pch = 0;
184 
185  if ((pch = strchr ((xdigits = xdigits_l), ch)) == 0)
186  {
187  pch = strchr ((xdigits = xdigits_u), ch);
188  }
189 
190  if (pch != 0)
191  {
192  val <<= 4;
193  val |= (pch - xdigits);
194 
195  if (++seen_xdigits > 4)
196  {
197  return (0);
198  }
199  continue;
200  }
201  if (ch == ':')
202  {
203 #if 0
204  curtok = address;
205 #endif
206 
207  if (!seen_xdigits)
208  {
209  if (colonp)
210  return (0);
211  colonp = tp;
212  continue;
213  }
214 
215  if (tp + 2 > endp)
216  {
217  return (0);
218  }
219 
220  *tp++ = (unsigned char)(val >> 8) & 0xff;
221  *tp++ = (unsigned char) val & 0xff;
222  seen_xdigits = 0;
223  val = 0;
224  continue;
225  }
226 
227  /* \todo Handle IPv4 mapped address (2001::192.168.0.1) */
228 #if 0
229  if (ch == '.' && ((tp + 4 /*NS_INADDRSZ*/) <= endp) &&
230  inet_pton4 (curtok, tp) > 0)
231  {
232  tp += 4 /*NS_INADDRSZ*/;
233  seen_xdigits = 0;
234  break; /* '\0' was seen by inet_pton4(). */
235  }
236 #endif
237  return (0);
238  }
239 
240  if (seen_xdigits)
241  {
242  if (tp + 2 > endp)
243  {
244  return (0);
245  }
246  *tp++ = (unsigned char)(val >> 8) & 0xff;
247  *tp++ = (unsigned char) val & 0xff;
248  }
249 
250  if (colonp != 0)
251  {
252  /*
253  * Since some memmove ()'s erroneously fail to handle
254  * overlapping regions, we'll do the shift by hand.
255  */
256  const int n = tp - colonp;
257  int i = 0;
258 
259  if (tp == endp)
260  {
261  return (0);
262  }
263 
264  for (i = 1; i <= n; i++)
265  {
266  endp[-i] = colonp[n - i];
267  colonp[n - i] = 0;
268  }
269 
270  tp = endp;
271  }
272 
273  if (tp != endp)
274  {
275  return (0);
276  }
277 
278  memcpy (addr, tmp, 16);
279  return (1);
280 }
281 
283 {
284  NS_LOG_FUNCTION (this);
285  memset (m_address, 0x00, 16);
286 }
287 
289 {
290  // Do not add function logging here, to avoid stack overflow
291  memcpy (m_address, addr.m_address, 16);
292 }
293 
295 {
296  // Do not add function logging here, to avoid stack overflow
297  memcpy (m_address, addr->m_address, 16);
298 }
299 
301 {
302  NS_LOG_FUNCTION (this << address);
303  AsciiToIpv6Host (address, m_address);
304 }
305 
307 {
308  NS_LOG_FUNCTION (this << &address);
309  /* 128 bit => 16 bytes */
310  memcpy (m_address, address, 16);
311 }
312 
314 {
315  /* do nothing */
316  NS_LOG_FUNCTION (this);
317 }
318 
319 void Ipv6Address::Set (char const* address)
320 {
321  NS_LOG_FUNCTION (this << address);
322  AsciiToIpv6Host (address, m_address);
323 }
324 
325 void Ipv6Address::Set (uint8_t address[16])
326 {
327  /* 128 bit => 16 bytes */
328  NS_LOG_FUNCTION (this << &address);
329  memcpy (m_address, address, 16);
330 }
331 
332 void Ipv6Address::Serialize (uint8_t buf[16]) const
333 {
334  NS_LOG_FUNCTION (this << &buf);
335  memcpy (buf, m_address, 16);
336 }
337 
338 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
339 {
340  NS_LOG_FUNCTION (&buf);
341  Ipv6Address ipv6 ((uint8_t*)buf);
342  return ipv6;
343 }
344 
346 {
347  NS_LOG_FUNCTION (addr);
348  uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
349  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
350  addr.Serialize (&buf[12]);
351  return (Ipv6Address (buf));
352 }
353 
355 {
356  NS_LOG_FUNCTION (this);
357  uint8_t buf[16];
358  Ipv4Address v4Addr;
359 
360  Serialize (buf);
361  v4Addr = Ipv4Address::Deserialize (&buf[12]);
362  return (v4Addr);
363 }
364 
366 {
367  NS_LOG_FUNCTION (addr << prefix);
368  Ipv6Address ret;
369  uint8_t buf[2];
370  uint8_t buf2[16];
371 
372  addr.CopyTo (buf);
373  prefix.GetBytes (buf2);
374 
375  memcpy (buf2 + 14, buf, 2);
376  buf2[11] = 0xff;
377  buf2[12] = 0xfe;
378 
379  ret.Set (buf2);
380  return ret;
381 }
382 
384 {
385  NS_LOG_FUNCTION (addr << prefix);
386  Ipv6Address ret;
387  uint8_t buf[16];
388  uint8_t buf2[16];
389 
390  addr.CopyTo (buf);
391  prefix.GetBytes (buf2);
392 
393  memcpy (buf2 + 8, buf, 3);
394  buf2[11] = 0xff;
395  buf2[12] = 0xfe;
396  memcpy (buf2 + 13, buf + 3, 3);
397  buf2[8] |= 0x02;
398 
399  ret.Set (buf2);
400  return ret;
401 }
402 
404 {
405  NS_LOG_FUNCTION (addr << prefix);
406  Ipv6Address ret;
407  uint8_t buf[8];
408  uint8_t buf2[16];
409 
410  addr.CopyTo (buf);
411  prefix.GetBytes (buf2);
412 
413  memcpy (buf2 + 8, buf, 8);
414 
415  ret.Set (buf2);
416  return ret;
417 }
418 
420 {
421  NS_LOG_FUNCTION (addr);
422  Ipv6Address ret;
423  uint8_t buf[2];
424  uint8_t buf2[16];
425 
426  addr.CopyTo (buf);
427 
428  memset (buf2, 0x00, sizeof (buf2));
429  buf2[0] = 0xfe;
430  buf2[1] = 0x80;
431  memcpy (buf2 + 14, buf, 2);
432  buf2[11] = 0xff;
433  buf2[12] = 0xfe;
434 
435  ret.Set (buf2);
436  return ret;
437 }
438 
440 {
441  NS_LOG_FUNCTION (addr);
442  Ipv6Address ret;
443  uint8_t buf[16];
444  uint8_t buf2[16];
445 
446  addr.CopyTo (buf);
447 
448  memset (buf2, 0x00, sizeof (buf2));
449  buf2[0] = 0xfe;
450  buf2[1] = 0x80;
451  memcpy (buf2 + 8, buf, 3);
452  buf2[11] = 0xff;
453  buf2[12] = 0xfe;
454  memcpy (buf2 + 13, buf + 3, 3);
455  buf2[8] |= 0x02;
456 
457  ret.Set (buf2);
458  return ret;
459 }
460 
462 {
463  NS_LOG_FUNCTION (addr);
464  Ipv6Address ret;
465  uint8_t buf[8];
466  uint8_t buf2[16];
467 
468  addr.CopyTo (buf);
469 
470  memset (buf2, 0x00, sizeof (buf2));
471  buf2[0] = 0xfe;
472  buf2[1] = 0x80;
473  memcpy (buf2 + 8, buf, 8);
474 
475  ret.Set (buf2);
476  return ret;
477 }
478 
480 {
481  NS_LOG_FUNCTION (addr);
482  uint8_t buf[16];
483  uint8_t buf2[16];
484  Ipv6Address ret;
485 
486  addr.Serialize (buf2);
487 
488  memset (buf, 0x00, sizeof (buf));
489  buf[0] = 0xff;
490  buf[1] = 0x02;
491  buf[11] = 0x01;
492  buf[12] = 0xff;
493  buf[13] = buf2[13];
494  buf[14] = buf2[14];
495  buf[15] = buf2[15];
496 
497  ret.Set (buf);
498  return ret;
499 }
500 
501 void Ipv6Address::Print (std::ostream& os) const
502 {
503  NS_LOG_FUNCTION (this << &os);
504 
505  // note: part of this function has been adapted from inet_ntop6 Linux function.
506  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
507  // Author: Paul Vixie, 1996.
508 
509  if (IsIpv4MappedAddress ())
510  {
511  os << "::ffff:"
512  << (unsigned int) m_address[12] << "."
513  << (unsigned int) m_address[13] << "."
514  << (unsigned int) m_address[14] << "."
515  << (unsigned int) m_address[15];
516  return;
517  }
518 
519  uint16_t address[8];
520  uint8_t i;
521 
522  for (i=0; i<8; i++)
523  {
524  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
525  }
526 
527  int8_t bestBase = -1;
528  int8_t bestLen = 0;
529  int8_t curBase = -1;
530  int8_t curLen = 0;
531 
532  for (i=0; i<8; i++)
533  {
534  if (address[i] == 0)
535  {
536  if (curBase == -1)
537  {
538  curBase = i;
539  curLen = 1;
540  }
541  else
542  {
543  curLen++;
544  }
545  }
546  else
547  {
548  if (curBase != -1)
549  {
550  if (bestBase == -1 || curLen > bestLen)
551  {
552  bestBase = curBase;
553  bestLen = curLen;
554  }
555  curBase = -1;
556  }
557  }
558  }
559  if (curBase != -1)
560  {
561  if (bestBase == -1 || curLen > bestLen)
562  {
563  bestBase = curBase;
564  bestLen = curLen;
565  }
566  }
567  if (bestBase != -1 && bestLen < 2)
568  {
569  bestBase = -1;
570  }
571 
572  for (i = 0; i < 8;) {
573  // Are we inside the best run of 0x00's?
574  if (i == bestBase)
575  {
576  os << ':';
577  i += bestLen;
578  continue;
579  }
580  // Are we following an initial run of 0x00s or any real hex?
581  if (i != 0)
582  {
583  os << ':';
584  }
585  os << std::hex << (unsigned int) address[i];
586  i++;
587  }
588  // Was it a trailing run of 0x00's?
589  if (bestBase != -1 && (bestBase + bestLen) == 8)
590  {
591  os << ':';
592  }
593  os << std::dec;
594 }
595 
597 {
598  NS_LOG_FUNCTION (this);
599  static Ipv6Address localhost ("::1");
600  return (*this == localhost);
601 }
602 
604 {
605  NS_LOG_FUNCTION (this);
606  if (m_address[0] == 0xff)
607  {
608  return true;
609  }
610  return false;
611 }
612 
614 {
615  NS_LOG_FUNCTION (this);
616  if (m_address[0] == 0xff && m_address[1] == 0x02)
617  {
618  return true;
619  }
620  return false;
621 }
622 
624 {
625  NS_LOG_FUNCTION (this);
626  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627  0x00, 0x00, 0xff, 0xff };
628  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
629  {
630  return (true);
631  }
632  return (false);
633 }
634 
636 {
637  NS_LOG_FUNCTION (this << prefix);
638  Ipv6Address ipv6;
639  uint8_t addr[16];
640  uint8_t pref[16];
641  unsigned int i = 0;
642 
643  memcpy (addr, m_address, 16);
644  ((Ipv6Prefix)prefix).GetBytes (pref);
645 
646  /* a little bit ugly... */
647  for (i = 0; i < 16; i++)
648  {
649  addr[i] = addr[i] & pref[i];
650  }
651  ipv6.Set (addr);
652  return ipv6;
653 }
654 
656 {
657  NS_LOG_FUNCTION (this);
658  uint8_t buf[16];
659 
660  Serialize (buf);
661 
662  if (buf[0] == 0xff &&
663  buf[1] == 0x02 &&
664  buf[11] == 0x01 &&
665  buf[12] == 0xff)
666  {
667  return true;
668  }
669  return false;
670 }
671 
673 {
674  NS_LOG_FUNCTION (this);
675  static Ipv6Address allnodes ("ff02::1");
676  return (*this == allnodes);
677 }
678 
680 {
681  NS_LOG_FUNCTION (this);
682  static Ipv6Address allrouters ("ff02::2");
683  return (*this == allrouters);
684 }
685 
687 {
688  NS_LOG_FUNCTION (this);
689  static Ipv6Address allhosts ("ff02::3");
690  return (*this == allhosts);
691 }
692 
693 bool Ipv6Address::IsAny () const
694 {
695  NS_LOG_FUNCTION (this);
696  static Ipv6Address any ("::");
697  return (*this == any);
698 }
699 
700 
702 {
703  NS_LOG_FUNCTION (this);
704  Ipv6Address documentation ("2001:db8::0");
705  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
706  {
707  return true;
708  }
709  return false;
710 }
711 
712 
714 {
715  NS_LOG_FUNCTION (address);
716  return address.CheckCompatible (GetType (), 16);
717 }
718 
719 Ipv6Address::operator Address () const
720 {
721  return ConvertTo ();
722 }
723 
725 {
726  NS_LOG_FUNCTION (this);
727  uint8_t buf[16];
728  Serialize (buf);
729  return Address (GetType (), buf, 16);
730 }
731 
733 {
734  NS_LOG_FUNCTION (address);
735  NS_ASSERT (address.CheckCompatible (GetType (), 16));
736  uint8_t buf[16];
737  address.CopyTo (buf);
738  return Deserialize (buf);
739 }
740 
741 uint8_t Ipv6Address::GetType (void)
742 {
744  static uint8_t type = Address::Register ();
745  return type;
746 }
747 
749 {
751  static Ipv6Address nmc ("ff02::1");
752  return nmc;
753 }
754 
756 {
758  static Ipv6Address rmc ("ff02::2");
759  return rmc;
760 }
761 
763 {
765  static Ipv6Address hmc ("ff02::3");
766  return hmc;
767 }
768 
770 {
772  static Ipv6Address loopback ("::1");
773  return loopback;
774 }
775 
777 {
779  static Ipv6Address zero ("::");
780  return zero;
781 }
782 
784 {
786  static Ipv6Address any ("::");
787  return any;
788 }
789 
791 {
793  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
794  return ones;
795 }
796 
797 void Ipv6Address::GetBytes (uint8_t buf[16]) const
798 {
799  NS_LOG_FUNCTION (this << &buf);
800  memcpy (buf, m_address, 16);
801 }
802 
804 {
805  NS_LOG_FUNCTION (this);
806  Ipv6Address linkLocal ("fe80::0");
807  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
808  {
809  return true;
810  }
811  return false;
812 }
813 
814 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
815 {
816  NS_LOG_FUNCTION (this << other);
817  if (!memcmp (m_address, other.m_address, 16))
818  {
819  return true;
820  }
821  return false;
822 }
823 
824 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
825 {
826  address.Print (os);
827  return os;
828 }
829 
830 std::istream& operator >> (std::istream& is, Ipv6Address& address)
831 {
832  std::string str;
833  is >> str;
834  address = Ipv6Address (str.c_str ());
835  return is;
836 }
837 
839 {
840  NS_LOG_FUNCTION (this);
841  memset (m_prefix, 0x00, 16);
842 }
843 
844 Ipv6Prefix::Ipv6Prefix (char const* prefix)
845 {
846  NS_LOG_FUNCTION (this << prefix);
847  AsciiToIpv6Host (prefix, m_prefix);
848 }
849 
850 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
851 {
852  NS_LOG_FUNCTION (this << &prefix);
853  memcpy (m_prefix, prefix, 16);
854 }
855 
856 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
857 {
858  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
859  unsigned int nb=0;
860  unsigned int mod=0;
861  unsigned int i=0;
862 
863  memset (m_prefix, 0x00, 16);
864 
865  NS_ASSERT (prefix <= 128);
866 
867  nb = prefix / 8;
868  mod = prefix % 8;
869 
870  // protect memset with 'nb > 0' check to suppress
871  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
872  if (nb > 0)
873  {
874  memset (m_prefix, 0xff, nb);
875  }
876  if (mod)
877  {
878  m_prefix[nb] = 0xff << (8-mod);
879  }
880 
881  if (nb < 16)
882  {
883  nb++;
884  for (i = nb; i < 16; i++)
885  {
886  m_prefix[i] = 0x00;
887  }
888  }
889 }
890 
892 {
893  memcpy (m_prefix, prefix.m_prefix, 16);
894 }
895 
897 {
898  memcpy (m_prefix, prefix->m_prefix, 16);
899 }
900 
902 {
903  /* do nothing */
904  NS_LOG_FUNCTION (this);
905 }
906 
908 {
909  NS_LOG_FUNCTION (this << a << b);
910  uint8_t addrA[16];
911  uint8_t addrB[16];
912  unsigned int i = 0;
913 
914  a.GetBytes (addrA);
915  b.GetBytes (addrB);
916 
917  /* a little bit ugly... */
918  for (i = 0; i < 16; i++)
919  {
920  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
921  {
922  return false;
923  }
924  }
925  return true;
926 }
927 
928 void Ipv6Prefix::Print (std::ostream &os) const
929 {
930  NS_LOG_FUNCTION (this << &os);
931 
932  os << "/" << (unsigned int) GetPrefixLength();
933 }
934 
936 {
938  static Ipv6Prefix prefix ((uint8_t)128);
939  return prefix;
940 }
941 
943 {
945  static Ipv6Prefix ones ((uint8_t)128);
946  return ones;
947 }
948 
950 {
952  static Ipv6Prefix prefix ((uint8_t)0);
953  return prefix;
954 }
955 
956 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
957 {
958  NS_LOG_FUNCTION (this << &buf);
959  memcpy (buf, m_prefix, 16);
960 }
961 
963 {
964  NS_LOG_FUNCTION (this);
965  uint8_t i = 0;
966  uint8_t prefixLength = 0;
967 
968  for(i = 0; i < 16; i++)
969  {
970  uint8_t mask = m_prefix[i];
971 
972  while(mask != 0)
973  {
974  mask = mask << 1;
975  prefixLength++;
976  }
977  }
978 
979  return prefixLength;
980 }
981 
982 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
983 {
984  if (!memcmp (m_prefix, other.m_prefix, 16))
985  {
986  return true;
987  }
988  return false;
989 }
990 
991 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
992 {
993  prefix.Print (os);
994  return os;
995 }
996 
997 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
998 {
999  std::string str;
1000  is >> str;
1001  prefix = Ipv6Prefix (str.c_str ());
1002  return is;
1003 }
1004 
1006 {
1007  uint8_t buf[16];
1008 
1009  x.GetBytes (buf);
1010 
1011  return lookuphash (buf, sizeof (buf), 0);
1012 }
1013 
1016 
1017 } /* namespace ns3 */
1018 
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:49
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:345
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()
Output the name of the function.
Definition: log.h:309
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: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
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:43
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:488
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")
This class can contain 16 bit addresses.
Definition: mac16-address.h:39
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.
~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:387
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() 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.