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  m_initialized = false;
286 }
287 
289 {
290  // Do not add function logging here, to avoid stack overflow
291  memcpy (m_address, addr.m_address, 16);
292  m_initialized = true;
293 }
294 
296 {
297  // Do not add function logging here, to avoid stack overflow
298  memcpy (m_address, addr->m_address, 16);
299  m_initialized = true;
300 }
301 
303 {
304  NS_LOG_FUNCTION (this << address);
306  m_initialized = true;
307 }
308 
310 {
311  NS_LOG_FUNCTION (this << &address);
312  /* 128 bit => 16 bytes */
313  memcpy (m_address, address, 16);
314  m_initialized = true;
315 }
316 
318 {
319  /* do nothing */
320  NS_LOG_FUNCTION (this);
321 }
322 
323 void Ipv6Address::Set (char const* address)
324 {
325  NS_LOG_FUNCTION (this << address);
327  m_initialized = true;
328 }
329 
330 void Ipv6Address::Set (uint8_t address[16])
331 {
332  /* 128 bit => 16 bytes */
333  NS_LOG_FUNCTION (this << &address);
334  memcpy (m_address, address, 16);
335  m_initialized = true;
336 }
337 
338 void Ipv6Address::Serialize (uint8_t buf[16]) const
339 {
340  NS_LOG_FUNCTION (this << &buf);
341  memcpy (buf, m_address, 16);
342 }
343 
344 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
345 {
346  NS_LOG_FUNCTION (&buf);
347  Ipv6Address ipv6 ((uint8_t*)buf);
348  ipv6.m_initialized = true;
349  return ipv6;
350 }
351 
353 {
354  NS_LOG_FUNCTION (addr);
355  uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
357  addr.Serialize (&buf[12]);
358  return (Ipv6Address (buf));
359 }
360 
362 {
363  NS_LOG_FUNCTION (this);
364  uint8_t buf[16];
365  Ipv4Address v4Addr;
366 
367  Serialize (buf);
368  v4Addr = Ipv4Address::Deserialize (&buf[12]);
369  return (v4Addr);
370 }
371 
373 {
374  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
375 
376  if (Mac64Address::IsMatchingType (addr))
377  {
379  }
380  else if (Mac48Address::IsMatchingType (addr))
381  {
383  }
384  else if (Mac16Address::IsMatchingType (addr))
385  {
387  }
388  else if (Mac8Address::IsMatchingType (addr))
389  {
391  }
392 
393  if (ipv6Addr.IsAny ())
394  {
395  NS_ABORT_MSG ("Unknown address type");
396  }
397  return ipv6Addr;
398 }
399 
401 {
402  NS_LOG_FUNCTION (addr << prefix);
403  Ipv6Address ret;
404  uint8_t buf[2];
405  uint8_t buf2[16];
406 
407  addr.CopyTo (buf);
408  prefix.GetBytes (buf2);
409  memset (buf2+8, 0, 8);
410 
411  memcpy (buf2 + 14, buf, 2);
412  buf2[11] = 0xff;
413  buf2[12] = 0xfe;
414 
415  ret.Set (buf2);
416  return ret;
417 }
418 
420 {
421  NS_LOG_FUNCTION (addr << prefix);
422  Ipv6Address ret;
423  uint8_t buf[16];
424  uint8_t buf2[16];
425 
426  addr.CopyTo (buf);
427  prefix.GetBytes (buf2);
428 
429  memcpy (buf2 + 8, buf, 3);
430  buf2[11] = 0xff;
431  buf2[12] = 0xfe;
432  memcpy (buf2 + 13, buf + 3, 3);
433  buf2[8] ^= 0x02;
434 
435  ret.Set (buf2);
436  return ret;
437 }
438 
440 {
441  NS_LOG_FUNCTION (addr << prefix);
442  Ipv6Address ret;
443  uint8_t buf[8];
444  uint8_t buf2[16];
445 
446  addr.CopyTo (buf);
447  prefix.GetBytes (buf2);
448 
449  memcpy (buf2 + 8, buf, 8);
450 
451  ret.Set (buf2);
452  return ret;
453 }
454 
456 {
457  NS_LOG_FUNCTION (addr << prefix);
458  Ipv6Address ret;
459  uint8_t buf[2];
460  uint8_t buf2[16];
461 
462  buf[0] = 0;
463  addr.CopyTo (&buf[1]);
464  prefix.GetBytes (buf2);
465  memset (buf2+8, 0, 8);
466 
467  memcpy (buf2 + 14, buf, 2);
468  buf2[11] = 0xff;
469  buf2[12] = 0xfe;
470 
471  ret.Set (buf2);
472  return ret;
473 }
474 
476 {
477  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
478 
479  if (Mac64Address::IsMatchingType (addr))
480  {
482  }
483  else if (Mac48Address::IsMatchingType (addr))
484  {
486  }
487  else if (Mac16Address::IsMatchingType (addr))
488  {
490  }
491  else if (Mac8Address::IsMatchingType (addr))
492  {
494  }
495 
496  if (ipv6Addr.IsAny ())
497  {
498  NS_ABORT_MSG ("Unknown address type");
499  }
500  return ipv6Addr;
501 }
502 
504 {
505  NS_LOG_FUNCTION (addr);
506  Ipv6Address ret;
507  uint8_t buf[2];
508  uint8_t buf2[16];
509 
510  addr.CopyTo (buf);
511 
512  memset (buf2, 0x00, sizeof (buf2));
513  buf2[0] = 0xfe;
514  buf2[1] = 0x80;
515  memcpy (buf2 + 14, buf, 2);
516  buf2[11] = 0xff;
517  buf2[12] = 0xfe;
518 
519  ret.Set (buf2);
520  return ret;
521 }
522 
524 {
525  NS_LOG_FUNCTION (addr);
526  Ipv6Address ret;
527  uint8_t buf[16];
528  uint8_t buf2[16];
529 
530  addr.CopyTo (buf);
531 
532  memset (buf2, 0x00, sizeof (buf2));
533  buf2[0] = 0xfe;
534  buf2[1] = 0x80;
535  memcpy (buf2 + 8, buf, 3);
536  buf2[11] = 0xff;
537  buf2[12] = 0xfe;
538  memcpy (buf2 + 13, buf + 3, 3);
539  buf2[8] ^= 0x02;
540 
541  ret.Set (buf2);
542  return ret;
543 }
544 
546 {
547  NS_LOG_FUNCTION (addr);
548  Ipv6Address ret;
549  uint8_t buf[8];
550  uint8_t buf2[16];
551 
552  addr.CopyTo (buf);
553 
554  memset (buf2, 0x00, sizeof (buf2));
555  buf2[0] = 0xfe;
556  buf2[1] = 0x80;
557  memcpy (buf2 + 8, buf, 8);
558 
559  ret.Set (buf2);
560  return ret;
561 }
562 
564 {
565  NS_LOG_FUNCTION (addr);
566  Ipv6Address ret;
567  uint8_t buf[2];
568  uint8_t buf2[16];
569 
570  buf[0] = 0;
571  addr.CopyTo (&buf[1]);
572 
573  memset (buf2, 0x00, sizeof (buf2));
574  buf2[0] = 0xfe;
575  buf2[1] = 0x80;
576  memcpy (buf2 + 14, buf, 2);
577  buf2[11] = 0xff;
578  buf2[12] = 0xfe;
579 
580  ret.Set (buf2);
581  return ret;
582 }
583 
585 {
586  NS_LOG_FUNCTION (addr);
587  uint8_t buf[16];
588  uint8_t buf2[16];
589  Ipv6Address ret;
590 
591  addr.Serialize (buf2);
592 
593  memset (buf, 0x00, sizeof (buf));
594  buf[0] = 0xff;
595  buf[1] = 0x02;
596  buf[11] = 0x01;
597  buf[12] = 0xff;
598  buf[13] = buf2[13];
599  buf[14] = buf2[14];
600  buf[15] = buf2[15];
601 
602  ret.Set (buf);
603  return ret;
604 }
605 
606 void Ipv6Address::Print (std::ostream& os) const
607 {
608  NS_LOG_FUNCTION (this << &os);
609 
610  // note: part of this function has been adapted from inet_ntop6 Linux function.
611  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
612  // Author: Paul Vixie, 1996.
613 
614  if (IsIpv4MappedAddress ())
615  {
616  os << "::ffff:"
617  << (unsigned int) m_address[12] << "."
618  << (unsigned int) m_address[13] << "."
619  << (unsigned int) m_address[14] << "."
620  << (unsigned int) m_address[15];
621  return;
622  }
623 
624  uint16_t address[8];
625  uint8_t i;
626 
627  for (i=0; i<8; i++)
628  {
629  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
630  }
631 
632  int8_t bestBase = -1;
633  int8_t bestLen = 0;
634  int8_t curBase = -1;
635  int8_t curLen = 0;
636 
637  for (i=0; i<8; i++)
638  {
639  if (address[i] == 0)
640  {
641  if (curBase == -1)
642  {
643  curBase = i;
644  curLen = 1;
645  }
646  else
647  {
648  curLen++;
649  }
650  }
651  else
652  {
653  if (curBase != -1)
654  {
655  if (bestBase == -1 || curLen > bestLen)
656  {
657  bestBase = curBase;
658  bestLen = curLen;
659  }
660  curBase = -1;
661  }
662  }
663  }
664  if (curBase != -1)
665  {
666  if (bestBase == -1 || curLen > bestLen)
667  {
668  bestBase = curBase;
669  bestLen = curLen;
670  }
671  }
672  if (bestBase != -1 && bestLen < 2)
673  {
674  bestBase = -1;
675  }
676 
677  for (i = 0; i < 8;) {
678  // Are we inside the best run of 0x00's?
679  if (i == bestBase)
680  {
681  os << ':';
682  i += bestLen;
683  continue;
684  }
685  // Are we following an initial run of 0x00s or any real hex?
686  if (i != 0)
687  {
688  os << ':';
689  }
690  os << std::hex << (unsigned int) address[i];
691  i++;
692  }
693  // Was it a trailing run of 0x00's?
694  if (bestBase != -1 && (bestBase + bestLen) == 8)
695  {
696  os << ':';
697  }
698  os << std::dec;
699 }
700 
702 {
703  NS_LOG_FUNCTION (this);
704  static Ipv6Address localhost ("::1");
705  return (*this == localhost);
706 }
707 
709 {
710  NS_LOG_FUNCTION (this);
711  if (m_address[0] == 0xff)
712  {
713  return true;
714  }
715  return false;
716 }
717 
719 {
720  NS_LOG_FUNCTION (this);
721  if (m_address[0] == 0xff && m_address[1] == 0x02)
722  {
723  return true;
724  }
725  return false;
726 }
727 
729 {
730  NS_LOG_FUNCTION (this);
731  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732  0x00, 0x00, 0xff, 0xff };
733  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
734  {
735  return (true);
736  }
737  return (false);
738 }
739 
741 {
742  NS_LOG_FUNCTION (this << prefix);
743  Ipv6Address ipv6;
744  uint8_t addr[16];
745  uint8_t pref[16];
746  unsigned int i = 0;
747 
748  memcpy (addr, m_address, 16);
749  ((Ipv6Prefix)prefix).GetBytes (pref);
750 
751  /* a little bit ugly... */
752  for (i = 0; i < 16; i++)
753  {
754  addr[i] = addr[i] & pref[i];
755  }
756  ipv6.Set (addr);
757  return ipv6;
758 }
759 
761 {
762  NS_LOG_FUNCTION (this);
763  uint8_t buf[16];
764 
765  Serialize (buf);
766 
767  if (buf[0] == 0xff &&
768  buf[1] == 0x02 &&
769  buf[11] == 0x01 &&
770  buf[12] == 0xff)
771  {
772  return true;
773  }
774  return false;
775 }
776 
778 {
779  NS_LOG_FUNCTION (this);
780  static Ipv6Address allNodesI ("ff01::1");
781  static Ipv6Address allNodesL ("ff02::1");
782  static Ipv6Address allNodesR ("ff03::1");
783  return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
784 }
785 
787 {
788  NS_LOG_FUNCTION (this);
789  static Ipv6Address allroutersI ("ff01::2");
790  static Ipv6Address allroutersL ("ff02::2");
791  static Ipv6Address allroutersR ("ff03::2");
792  static Ipv6Address allroutersS ("ff05::2");
793  return (*this == allroutersI || *this == allroutersL || *this == allroutersR || *this == allroutersS);
794 }
795 
796 bool Ipv6Address::IsAny () const
797 {
798  NS_LOG_FUNCTION (this);
799  static Ipv6Address any ("::");
800  return (*this == any);
801 }
802 
803 
805 {
806  NS_LOG_FUNCTION (this);
807  Ipv6Address documentation ("2001:db8::0");
808  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
809  {
810  return true;
811  }
812  return false;
813 }
814 
815 bool Ipv6Address::HasPrefix (Ipv6Prefix const& prefix) const
816 {
817  NS_LOG_FUNCTION (this << prefix);
818 
819  Ipv6Address masked = CombinePrefix (prefix);
821 
822  return (masked == reference);
823 }
824 
825 
827 {
829  return address.CheckCompatible (GetType (), 16);
830 }
831 
832 Ipv6Address::operator Address () const
833 {
834  return ConvertTo ();
835 }
836 
838 {
839  NS_LOG_FUNCTION (this);
840  uint8_t buf[16];
841  Serialize (buf);
842  return Address (GetType (), buf, 16);
843 }
844 
846 {
848  NS_ASSERT (address.CheckCompatible (GetType (), 16));
849  uint8_t buf[16];
850  address.CopyTo (buf);
851  return Deserialize (buf);
852 }
853 
854 uint8_t Ipv6Address::GetType (void)
855 {
857  static uint8_t type = Address::Register ();
858  return type;
859 }
860 
862 {
864  static Ipv6Address nmc ("ff02::1");
865  return nmc;
866 }
867 
869 {
871  static Ipv6Address rmc ("ff02::2");
872  return rmc;
873 }
874 
876 {
878  static Ipv6Address hmc ("ff02::3");
879  return hmc;
880 }
881 
883 {
885  static Ipv6Address loopback ("::1");
886  return loopback;
887 }
888 
890 {
892  static Ipv6Address zero ("::");
893  return zero;
894 }
895 
897 {
899  static Ipv6Address any ("::");
900  return any;
901 }
902 
904 {
906  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
907  return ones;
908 }
909 
910 void Ipv6Address::GetBytes (uint8_t buf[16]) const
911 {
912  NS_LOG_FUNCTION (this << &buf);
913  memcpy (buf, m_address, 16);
914 }
915 
917 {
918  NS_LOG_FUNCTION (this);
919  Ipv6Address linkLocal ("fe80::0");
920  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
921  {
922  return true;
923  }
924  return false;
925 }
926 
927 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
928 {
929  NS_LOG_FUNCTION (this << other);
930  if (!memcmp (m_address, other.m_address, 16))
931  {
932  return true;
933  }
934  return false;
935 }
936 
937 bool Ipv6Address::IsInitialized (void) const
938 {
939  NS_LOG_FUNCTION (this);
940  return (m_initialized);
941 }
942 
943 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
944 {
945  address.Print (os);
946  return os;
947 }
948 
949 std::istream& operator >> (std::istream& is, Ipv6Address& address)
950 {
951  std::string str;
952  is >> str;
953  address = Ipv6Address (str.c_str ());
954  return is;
955 }
956 
958 {
959  NS_LOG_FUNCTION (this);
960  memset (m_prefix, 0x00, 16);
961  m_prefixLength = 64;
962 }
963 
964 Ipv6Prefix::Ipv6Prefix (char const* prefix)
965 {
966  NS_LOG_FUNCTION (this << prefix);
967  AsciiToIpv6Host (prefix, m_prefix);
969 }
970 
971 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
972 {
973  NS_LOG_FUNCTION (this << &prefix);
974  memcpy (m_prefix, prefix, 16);
976 }
977 
978 Ipv6Prefix::Ipv6Prefix (char const* prefix, uint8_t prefixLength)
979 {
980  NS_LOG_FUNCTION (this << prefix);
981  AsciiToIpv6Host (prefix, m_prefix);
982 
983  uint8_t autoLength = GetMinimumPrefixLength ();
984  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
985 
986  m_prefixLength = prefixLength;
987 }
988 
989 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16], uint8_t prefixLength)
990 {
991  NS_LOG_FUNCTION (this << &prefix);
992  memcpy (m_prefix, prefix, 16);
993 
994  uint8_t autoLength = GetMinimumPrefixLength ();
995  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
996 
997  m_prefixLength = prefixLength;
998 }
999 
1000 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
1001 {
1002  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
1003  unsigned int nb=0;
1004  unsigned int mod=0;
1005  unsigned int i=0;
1006 
1007  memset (m_prefix, 0x00, 16);
1008  m_prefixLength = prefix;
1009 
1010  NS_ASSERT (prefix <= 128);
1011 
1012  nb = prefix / 8;
1013  mod = prefix % 8;
1014 
1015  // protect memset with 'nb > 0' check to suppress
1016  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
1017  if (nb > 0)
1018  {
1019  memset (m_prefix, 0xff, nb);
1020  }
1021  if (mod)
1022  {
1023  m_prefix[nb] = 0xff << (8-mod);
1024  }
1025 
1026  if (nb < 16)
1027  {
1028  nb++;
1029  for (i = nb; i < 16; i++)
1030  {
1031  m_prefix[i] = 0x00;
1032  }
1033  }
1034 }
1035 
1037 {
1038  memcpy (m_prefix, prefix.m_prefix, 16);
1039  m_prefixLength = prefix.m_prefixLength;
1040 }
1041 
1043 {
1044  memcpy (m_prefix, prefix->m_prefix, 16);
1045  m_prefixLength = prefix->m_prefixLength;
1046 }
1047 
1049 {
1050  /* do nothing */
1051  NS_LOG_FUNCTION (this);
1052 }
1053 
1055 {
1056  NS_LOG_FUNCTION (this << a << b);
1057  uint8_t addrA[16];
1058  uint8_t addrB[16];
1059  unsigned int i = 0;
1060 
1061  a.GetBytes (addrA);
1062  b.GetBytes (addrB);
1063 
1064  /* a little bit ugly... */
1065  for (i = 0; i < 16; i++)
1066  {
1067  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
1068  {
1069  return false;
1070  }
1071  }
1072  return true;
1073 }
1074 
1075 void Ipv6Prefix::Print (std::ostream &os) const
1076 {
1077  NS_LOG_FUNCTION (this << &os);
1078 
1079  os << "/" << (unsigned int) GetPrefixLength();
1080 }
1081 
1083 {
1085  static Ipv6Prefix prefix ((uint8_t)128);
1086  return prefix;
1087 }
1088 
1090 {
1092  static Ipv6Prefix ones ((uint8_t)128);
1093  return ones;
1094 }
1095 
1097 {
1099  static Ipv6Prefix prefix ((uint8_t)0);
1100  return prefix;
1101 }
1102 
1103 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
1104 {
1105  NS_LOG_FUNCTION (this << &buf);
1106  memcpy (buf, m_prefix, 16);
1107 }
1108 
1110 {
1111  NS_LOG_FUNCTION (this);
1112  return m_prefixLength;
1113 }
1114 
1115 void Ipv6Prefix::SetPrefixLength (uint8_t prefixLength)
1116 {
1117  NS_LOG_FUNCTION (this);
1118  m_prefixLength = prefixLength;
1119 }
1120 
1122 {
1123  NS_LOG_FUNCTION (this);
1124 
1125  uint8_t prefixLength = 0;
1126  bool stop = false;
1127 
1128  for(int8_t i=15; i>=0 && !stop; i--)
1129  {
1130  uint8_t mask = m_prefix[i];
1131 
1132  for(uint8_t j=0; j<8 && !stop; j++)
1133  {
1134  if ((mask & 1) == 0)
1135  {
1136  mask = mask >> 1;
1137  prefixLength++;
1138  }
1139  else
1140  {
1141  stop = true;
1142  }
1143  }
1144  }
1145 
1146  return 128 - prefixLength;
1147 }
1148 
1149 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
1150 {
1151  if (!memcmp (m_prefix, other.m_prefix, 16))
1152  {
1153  return true;
1154  }
1155  return false;
1156 }
1157 
1158 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1159 {
1160  prefix.Print (os);
1161  return os;
1162 }
1163 
1164 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1165 {
1166  std::string str;
1167  is >> str;
1168  prefix = Ipv6Prefix (str.c_str ());
1169  return is;
1170 }
1171 
1173 {
1174  uint8_t buf[16];
1175 
1176  x.GetBytes (buf);
1177 
1178  return lookuphash (buf, sizeof (buf), 0);
1179 }
1180 
1183 
1184 } /* namespace ns3 */
1185 
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:417
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.
void SetPrefixLength(uint8_t prefixLength)
Set prefix length.
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:205
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
uint8_t m_prefixLength
The prefix length.
Definition: ipv6-address.h:599
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
NS_DEPRECATED_3_31 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).
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix) const
Combine this address with a prefix.
uint8_t GetMinimumPrefixLength() const
Get the minimum prefix length, i.e., 128 - the length of the largest sequence trailing zeroes...
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).
bool HasPrefix(Ipv6Prefix const &prefix) const
Compares an address and a prefix.
address
Definition: first.py:44
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:594
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_3_31 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).
#define NS_ASSERT_MSG(condition, message)
At runtime, in debugging builds, if this condition is not true, the program prints the message to out...
Definition: assert.h:88
Describes an IPv6 address.
Definition: ipv6-address.h:49
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
bool m_initialized
IPv6 address has been explicitly initialized to a valid value.
Definition: ipv6-address.h:418
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:455
static bool IsMatchingType(const Address &address)
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
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.
bool IsInitialized(void) const
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.