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);
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);
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  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
367 
368  if (Mac64Address::IsMatchingType (addr))
369  {
371  }
372  else if (Mac48Address::IsMatchingType (addr))
373  {
375  }
376  else if (Mac16Address::IsMatchingType (addr))
377  {
379  }
380  else if (Mac8Address::IsMatchingType (addr))
381  {
383  }
384 
385  if (ipv6Addr.IsAny ())
386  {
387  NS_ABORT_MSG ("Unknown address type");
388  }
389  return ipv6Addr;
390 }
391 
393 {
394  NS_LOG_FUNCTION (addr << prefix);
395  Ipv6Address ret;
396  uint8_t buf[2];
397  uint8_t buf2[16];
398 
399  addr.CopyTo (buf);
400  prefix.GetBytes (buf2);
401  memset (buf2+8, 0, 8);
402 
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 << prefix);
414  Ipv6Address ret;
415  uint8_t buf[16];
416  uint8_t buf2[16];
417 
418  addr.CopyTo (buf);
419  prefix.GetBytes (buf2);
420 
421  memcpy (buf2 + 8, buf, 3);
422  buf2[11] = 0xff;
423  buf2[12] = 0xfe;
424  memcpy (buf2 + 13, buf + 3, 3);
425  buf2[8] ^= 0x02;
426 
427  ret.Set (buf2);
428  return ret;
429 }
430 
432 {
433  NS_LOG_FUNCTION (addr << prefix);
434  Ipv6Address ret;
435  uint8_t buf[8];
436  uint8_t buf2[16];
437 
438  addr.CopyTo (buf);
439  prefix.GetBytes (buf2);
440 
441  memcpy (buf2 + 8, buf, 8);
442 
443  ret.Set (buf2);
444  return ret;
445 }
446 
448 {
449  NS_LOG_FUNCTION (addr << prefix);
450  Ipv6Address ret;
451  uint8_t buf[2];
452  uint8_t buf2[16];
453 
454  buf[0] = 0;
455  addr.CopyTo (&buf[1]);
456  prefix.GetBytes (buf2);
457  memset (buf2+8, 0, 8);
458 
459  memcpy (buf2 + 14, buf, 2);
460  buf2[11] = 0xff;
461  buf2[12] = 0xfe;
462 
463  ret.Set (buf2);
464  return ret;
465 }
466 
468 {
469  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
470 
471  if (Mac64Address::IsMatchingType (addr))
472  {
474  }
475  else if (Mac48Address::IsMatchingType (addr))
476  {
478  }
479  else if (Mac16Address::IsMatchingType (addr))
480  {
482  }
483  else if (Mac8Address::IsMatchingType (addr))
484  {
486  }
487 
488  if (ipv6Addr.IsAny ())
489  {
490  NS_ABORT_MSG ("Unknown address type");
491  }
492  return ipv6Addr;
493 }
494 
496 {
497  NS_LOG_FUNCTION (addr);
498  Ipv6Address ret;
499  uint8_t buf[2];
500  uint8_t buf2[16];
501 
502  addr.CopyTo (buf);
503 
504  memset (buf2, 0x00, sizeof (buf2));
505  buf2[0] = 0xfe;
506  buf2[1] = 0x80;
507  memcpy (buf2 + 14, buf, 2);
508  buf2[11] = 0xff;
509  buf2[12] = 0xfe;
510 
511  ret.Set (buf2);
512  return ret;
513 }
514 
516 {
517  NS_LOG_FUNCTION (addr);
518  Ipv6Address ret;
519  uint8_t buf[16];
520  uint8_t buf2[16];
521 
522  addr.CopyTo (buf);
523 
524  memset (buf2, 0x00, sizeof (buf2));
525  buf2[0] = 0xfe;
526  buf2[1] = 0x80;
527  memcpy (buf2 + 8, buf, 3);
528  buf2[11] = 0xff;
529  buf2[12] = 0xfe;
530  memcpy (buf2 + 13, buf + 3, 3);
531  buf2[8] ^= 0x02;
532 
533  ret.Set (buf2);
534  return ret;
535 }
536 
538 {
539  NS_LOG_FUNCTION (addr);
540  Ipv6Address ret;
541  uint8_t buf[8];
542  uint8_t buf2[16];
543 
544  addr.CopyTo (buf);
545 
546  memset (buf2, 0x00, sizeof (buf2));
547  buf2[0] = 0xfe;
548  buf2[1] = 0x80;
549  memcpy (buf2 + 8, buf, 8);
550 
551  ret.Set (buf2);
552  return ret;
553 }
554 
556 {
557  NS_LOG_FUNCTION (addr);
558  Ipv6Address ret;
559  uint8_t buf[2];
560  uint8_t buf2[16];
561 
562  buf[0] = 0;
563  addr.CopyTo (&buf[1]);
564 
565  memset (buf2, 0x00, sizeof (buf2));
566  buf2[0] = 0xfe;
567  buf2[1] = 0x80;
568  memcpy (buf2 + 14, buf, 2);
569  buf2[11] = 0xff;
570  buf2[12] = 0xfe;
571 
572  ret.Set (buf2);
573  return ret;
574 }
575 
577 {
578  NS_LOG_FUNCTION (addr);
579  uint8_t buf[16];
580  uint8_t buf2[16];
581  Ipv6Address ret;
582 
583  addr.Serialize (buf2);
584 
585  memset (buf, 0x00, sizeof (buf));
586  buf[0] = 0xff;
587  buf[1] = 0x02;
588  buf[11] = 0x01;
589  buf[12] = 0xff;
590  buf[13] = buf2[13];
591  buf[14] = buf2[14];
592  buf[15] = buf2[15];
593 
594  ret.Set (buf);
595  return ret;
596 }
597 
598 void Ipv6Address::Print (std::ostream& os) const
599 {
600  NS_LOG_FUNCTION (this << &os);
601 
602  // note: part of this function has been adapted from inet_ntop6 Linux function.
603  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
604  // Author: Paul Vixie, 1996.
605 
606  if (IsIpv4MappedAddress ())
607  {
608  os << "::ffff:"
609  << (unsigned int) m_address[12] << "."
610  << (unsigned int) m_address[13] << "."
611  << (unsigned int) m_address[14] << "."
612  << (unsigned int) m_address[15];
613  return;
614  }
615 
616  uint16_t address[8];
617  uint8_t i;
618 
619  for (i=0; i<8; i++)
620  {
621  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
622  }
623 
624  int8_t bestBase = -1;
625  int8_t bestLen = 0;
626  int8_t curBase = -1;
627  int8_t curLen = 0;
628 
629  for (i=0; i<8; i++)
630  {
631  if (address[i] == 0)
632  {
633  if (curBase == -1)
634  {
635  curBase = i;
636  curLen = 1;
637  }
638  else
639  {
640  curLen++;
641  }
642  }
643  else
644  {
645  if (curBase != -1)
646  {
647  if (bestBase == -1 || curLen > bestLen)
648  {
649  bestBase = curBase;
650  bestLen = curLen;
651  }
652  curBase = -1;
653  }
654  }
655  }
656  if (curBase != -1)
657  {
658  if (bestBase == -1 || curLen > bestLen)
659  {
660  bestBase = curBase;
661  bestLen = curLen;
662  }
663  }
664  if (bestBase != -1 && bestLen < 2)
665  {
666  bestBase = -1;
667  }
668 
669  for (i = 0; i < 8;) {
670  // Are we inside the best run of 0x00's?
671  if (i == bestBase)
672  {
673  os << ':';
674  i += bestLen;
675  continue;
676  }
677  // Are we following an initial run of 0x00s or any real hex?
678  if (i != 0)
679  {
680  os << ':';
681  }
682  os << std::hex << (unsigned int) address[i];
683  i++;
684  }
685  // Was it a trailing run of 0x00's?
686  if (bestBase != -1 && (bestBase + bestLen) == 8)
687  {
688  os << ':';
689  }
690  os << std::dec;
691 }
692 
694 {
695  NS_LOG_FUNCTION (this);
696  static Ipv6Address localhost ("::1");
697  return (*this == localhost);
698 }
699 
701 {
702  NS_LOG_FUNCTION (this);
703  if (m_address[0] == 0xff)
704  {
705  return true;
706  }
707  return false;
708 }
709 
711 {
712  NS_LOG_FUNCTION (this);
713  if (m_address[0] == 0xff && m_address[1] == 0x02)
714  {
715  return true;
716  }
717  return false;
718 }
719 
721 {
722  NS_LOG_FUNCTION (this);
723  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724  0x00, 0x00, 0xff, 0xff };
725  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
726  {
727  return (true);
728  }
729  return (false);
730 }
731 
733 {
734  NS_LOG_FUNCTION (this << prefix);
735  Ipv6Address ipv6;
736  uint8_t addr[16];
737  uint8_t pref[16];
738  unsigned int i = 0;
739 
740  memcpy (addr, m_address, 16);
741  ((Ipv6Prefix)prefix).GetBytes (pref);
742 
743  /* a little bit ugly... */
744  for (i = 0; i < 16; i++)
745  {
746  addr[i] = addr[i] & pref[i];
747  }
748  ipv6.Set (addr);
749  return ipv6;
750 }
751 
753 {
754  NS_LOG_FUNCTION (this);
755  uint8_t buf[16];
756 
757  Serialize (buf);
758 
759  if (buf[0] == 0xff &&
760  buf[1] == 0x02 &&
761  buf[11] == 0x01 &&
762  buf[12] == 0xff)
763  {
764  return true;
765  }
766  return false;
767 }
768 
770 {
771  NS_LOG_FUNCTION (this);
772  static Ipv6Address allNodesI ("ff01::1");
773  static Ipv6Address allNodesL ("ff02::1");
774  static Ipv6Address allNodesR ("ff03::1");
775  return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
776 }
777 
779 {
780  NS_LOG_FUNCTION (this);
781  static Ipv6Address allroutersI ("ff01::2");
782  static Ipv6Address allroutersL ("ff02::2");
783  static Ipv6Address allroutersR ("ff03::2");
784  static Ipv6Address allroutersS ("ff05::2");
785  return (*this == allroutersI || *this == allroutersL || *this == allroutersR || *this == allroutersS);
786 }
787 
789 {
790  NS_LOG_FUNCTION (this);
791  static Ipv6Address allhosts ("ff02::3");
792  return (*this == allhosts);
793 }
794 
795 bool Ipv6Address::IsAny () const
796 {
797  NS_LOG_FUNCTION (this);
798  static Ipv6Address any ("::");
799  return (*this == any);
800 }
801 
802 
804 {
805  NS_LOG_FUNCTION (this);
806  Ipv6Address documentation ("2001:db8::0");
807  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
808  {
809  return true;
810  }
811  return false;
812 }
813 
814 
816 {
818  return address.CheckCompatible (GetType (), 16);
819 }
820 
821 Ipv6Address::operator Address () const
822 {
823  return ConvertTo ();
824 }
825 
827 {
828  NS_LOG_FUNCTION (this);
829  uint8_t buf[16];
830  Serialize (buf);
831  return Address (GetType (), buf, 16);
832 }
833 
835 {
837  NS_ASSERT (address.CheckCompatible (GetType (), 16));
838  uint8_t buf[16];
839  address.CopyTo (buf);
840  return Deserialize (buf);
841 }
842 
843 uint8_t Ipv6Address::GetType (void)
844 {
846  static uint8_t type = Address::Register ();
847  return type;
848 }
849 
851 {
853  static Ipv6Address nmc ("ff02::1");
854  return nmc;
855 }
856 
858 {
860  static Ipv6Address rmc ("ff02::2");
861  return rmc;
862 }
863 
865 {
867  static Ipv6Address hmc ("ff02::3");
868  return hmc;
869 }
870 
872 {
874  static Ipv6Address loopback ("::1");
875  return loopback;
876 }
877 
879 {
881  static Ipv6Address zero ("::");
882  return zero;
883 }
884 
886 {
888  static Ipv6Address any ("::");
889  return any;
890 }
891 
893 {
895  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
896  return ones;
897 }
898 
899 void Ipv6Address::GetBytes (uint8_t buf[16]) const
900 {
901  NS_LOG_FUNCTION (this << &buf);
902  memcpy (buf, m_address, 16);
903 }
904 
906 {
907  NS_LOG_FUNCTION (this);
908  Ipv6Address linkLocal ("fe80::0");
909  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
910  {
911  return true;
912  }
913  return false;
914 }
915 
916 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
917 {
918  NS_LOG_FUNCTION (this << other);
919  if (!memcmp (m_address, other.m_address, 16))
920  {
921  return true;
922  }
923  return false;
924 }
925 
926 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
927 {
928  address.Print (os);
929  return os;
930 }
931 
932 std::istream& operator >> (std::istream& is, Ipv6Address& address)
933 {
934  std::string str;
935  is >> str;
936  address = Ipv6Address (str.c_str ());
937  return is;
938 }
939 
941 {
942  NS_LOG_FUNCTION (this);
943  memset (m_prefix, 0x00, 16);
944 }
945 
946 Ipv6Prefix::Ipv6Prefix (char const* prefix)
947 {
948  NS_LOG_FUNCTION (this << prefix);
949  AsciiToIpv6Host (prefix, m_prefix);
950 }
951 
952 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
953 {
954  NS_LOG_FUNCTION (this << &prefix);
955  memcpy (m_prefix, prefix, 16);
956 }
957 
958 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
959 {
960  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
961  unsigned int nb=0;
962  unsigned int mod=0;
963  unsigned int i=0;
964 
965  memset (m_prefix, 0x00, 16);
966 
967  NS_ASSERT (prefix <= 128);
968 
969  nb = prefix / 8;
970  mod = prefix % 8;
971 
972  // protect memset with 'nb > 0' check to suppress
973  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
974  if (nb > 0)
975  {
976  memset (m_prefix, 0xff, nb);
977  }
978  if (mod)
979  {
980  m_prefix[nb] = 0xff << (8-mod);
981  }
982 
983  if (nb < 16)
984  {
985  nb++;
986  for (i = nb; i < 16; i++)
987  {
988  m_prefix[i] = 0x00;
989  }
990  }
991 }
992 
994 {
995  memcpy (m_prefix, prefix.m_prefix, 16);
996 }
997 
999 {
1000  memcpy (m_prefix, prefix->m_prefix, 16);
1001 }
1002 
1004 {
1005  /* do nothing */
1006  NS_LOG_FUNCTION (this);
1007 }
1008 
1010 {
1011  NS_LOG_FUNCTION (this << a << b);
1012  uint8_t addrA[16];
1013  uint8_t addrB[16];
1014  unsigned int i = 0;
1015 
1016  a.GetBytes (addrA);
1017  b.GetBytes (addrB);
1018 
1019  /* a little bit ugly... */
1020  for (i = 0; i < 16; i++)
1021  {
1022  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
1023  {
1024  return false;
1025  }
1026  }
1027  return true;
1028 }
1029 
1030 void Ipv6Prefix::Print (std::ostream &os) const
1031 {
1032  NS_LOG_FUNCTION (this << &os);
1033 
1034  os << "/" << (unsigned int) GetPrefixLength();
1035 }
1036 
1038 {
1040  static Ipv6Prefix prefix ((uint8_t)128);
1041  return prefix;
1042 }
1043 
1045 {
1047  static Ipv6Prefix ones ((uint8_t)128);
1048  return ones;
1049 }
1050 
1052 {
1054  static Ipv6Prefix prefix ((uint8_t)0);
1055  return prefix;
1056 }
1057 
1058 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
1059 {
1060  NS_LOG_FUNCTION (this << &buf);
1061  memcpy (buf, m_prefix, 16);
1062 }
1063 
1065 {
1066  NS_LOG_FUNCTION (this);
1067  uint8_t i = 0;
1068  uint8_t prefixLength = 0;
1069 
1070  for(i = 0; i < 16; i++)
1071  {
1072  uint8_t mask = m_prefix[i];
1073 
1074  while(mask != 0)
1075  {
1076  mask = mask << 1;
1077  prefixLength++;
1078  }
1079  }
1080 
1081  return prefixLength;
1082 }
1083 
1084 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
1085 {
1086  if (!memcmp (m_prefix, other.m_prefix, 16))
1087  {
1088  return true;
1089  }
1090  return false;
1091 }
1092 
1093 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1094 {
1095  prefix.Print (os);
1096  return os;
1097 }
1098 
1099 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1100 {
1101  std::string str;
1102  is >> str;
1103  prefix = Ipv6Prefix (str.c_str ());
1104  return is;
1105 }
1106 
1108 {
1109  uint8_t buf[16];
1110 
1111  x.GetBytes (buf);
1112 
1113  return lookuphash (buf, sizeof (buf), 0);
1114 }
1115 
1118 
1119 } /* namespace ns3 */
1120 
static bool IsMatchingType(const Address &address)
If the Address matches the type.
static bool IsMatchingType(const Address &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
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
Ipv6Address()
Default constructor.
uint8_t m_address[16]
The address representation on 128 bits (16 bytes).
Definition: ipv6-address.h:412
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
Ipv6Prefix()
Default constructor.
static Mac16Address ConvertFrom(const Address &address)
static bool IsMatchingType(const Address &address)
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Address mac)
Make the autoconfigured link-local IPv6 address from a Mac address.
#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.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
~Ipv6Prefix()
Destructor.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
#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
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Address ConvertTo(void) const
convert the IPv6Address object to an Address object.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:204
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
void CopyTo(uint8_t buffer[2]) const
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
Definition: mac8-address.cc:63
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
size_t operator()(Ipv6Address const &x) const
Unary operator to hash IPv6 address.
a polymophic address class
Definition: address.h:90
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
an EUI-64 address
Definition: mac64-address.h:43
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
void CopyTo(uint8_t buffer[6]) const
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).
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
void CopyTo(uint8_t buffer[8]) const
A class used for addressing MAC8 MAC&#39;s.
Definition: mac8-address.h:42
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
void Set(char const *address)
Sets an Ipv6Address by parsing the input C-string.
static Mac48Address ConvertFrom(const Address &address)
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
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
Every class exported by the ns3 library is enclosed in the ns3 namespace.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
address
Definition: first.py:37
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:550
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
uint8_t GetPrefixLength() const
Get prefix length.
NS_DEPRECATED bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
bool IsEqual(const Ipv6Prefix &other) const
Comparison operation between two Ipv6Prefix.
void Print(std::ostream &os) const
Print this address to the given output stream.
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Describes an IPv6 address.
Definition: ipv6-address.h:49
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
static Mac64Address ConvertFrom(const Address &address)
~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:449
static bool IsMatchingType(const Address &address)
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
static uint8_t GetType(void)
Return the Type of address.
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 CopyTo(uint8_t *pBuffer) const
Writes address to buffer parameter.
Definition: mac8-address.cc:80
bool IsAny() const
If the IPv6 address is the "Any" address.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
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.