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  Ipv6Address ipv6PrefixAddr = Ipv6Address::GetOnes ().CombinePrefix(prefix);
403  return MakeAutoconfiguredAddress (addr, ipv6PrefixAddr);
404 }
405 
407 {
408  NS_LOG_FUNCTION (addr << prefix);
409  Ipv6Address ret;
410  uint8_t buf[2];
411  uint8_t buf2[16];
412 
413  addr.CopyTo (buf);
414  prefix.GetBytes (buf2);
415  memset (buf2+8, 0, 8);
416 
417  memcpy (buf2 + 14, buf, 2);
418  buf2[11] = 0xff;
419  buf2[12] = 0xfe;
420 
421  ret.Set (buf2);
422  return ret;
423 }
424 
426 {
427  NS_LOG_FUNCTION (addr << prefix);
428  Ipv6Address ret;
429  uint8_t buf[16];
430  uint8_t buf2[16];
431 
432  addr.CopyTo (buf);
433  prefix.GetBytes (buf2);
434 
435  memcpy (buf2 + 8, buf, 3);
436  buf2[11] = 0xff;
437  buf2[12] = 0xfe;
438  memcpy (buf2 + 13, buf + 3, 3);
439  buf2[8] ^= 0x02;
440 
441  ret.Set (buf2);
442  return ret;
443 }
444 
446 {
447  NS_LOG_FUNCTION (addr << prefix);
448  Ipv6Address ret;
449  uint8_t buf[8];
450  uint8_t buf2[16];
451 
452  addr.CopyTo (buf);
453  prefix.GetBytes (buf2);
454 
455  memcpy (buf2 + 8, buf, 8);
456 
457  ret.Set (buf2);
458  return ret;
459 }
460 
462 {
463  NS_LOG_FUNCTION (addr << prefix);
464  Ipv6Address ret;
465  uint8_t buf[2];
466  uint8_t buf2[16];
467 
468  buf[0] = 0;
469  addr.CopyTo (&buf[1]);
470  prefix.GetBytes (buf2);
471  memset (buf2+8, 0, 8);
472 
473  memcpy (buf2 + 14, buf, 2);
474  buf2[11] = 0xff;
475  buf2[12] = 0xfe;
476 
477  ret.Set (buf2);
478  return ret;
479 }
480 
482 {
483  Ipv6Address ipv6Addr = Ipv6Address::GetAny ();
484 
485  if (Mac64Address::IsMatchingType (addr))
486  {
488  }
489  else if (Mac48Address::IsMatchingType (addr))
490  {
492  }
493  else if (Mac16Address::IsMatchingType (addr))
494  {
496  }
497  else if (Mac8Address::IsMatchingType (addr))
498  {
500  }
501 
502  if (ipv6Addr.IsAny ())
503  {
504  NS_ABORT_MSG ("Unknown address type");
505  }
506  return ipv6Addr;
507 }
508 
510 {
511  NS_LOG_FUNCTION (addr);
512  Ipv6Address ret;
513  uint8_t buf[2];
514  uint8_t buf2[16];
515 
516  addr.CopyTo (buf);
517 
518  memset (buf2, 0x00, sizeof (buf2));
519  buf2[0] = 0xfe;
520  buf2[1] = 0x80;
521  memcpy (buf2 + 14, buf, 2);
522  buf2[11] = 0xff;
523  buf2[12] = 0xfe;
524 
525  ret.Set (buf2);
526  return ret;
527 }
528 
530 {
531  NS_LOG_FUNCTION (addr);
532  Ipv6Address ret;
533  uint8_t buf[16];
534  uint8_t buf2[16];
535 
536  addr.CopyTo (buf);
537 
538  memset (buf2, 0x00, sizeof (buf2));
539  buf2[0] = 0xfe;
540  buf2[1] = 0x80;
541  memcpy (buf2 + 8, buf, 3);
542  buf2[11] = 0xff;
543  buf2[12] = 0xfe;
544  memcpy (buf2 + 13, buf + 3, 3);
545  buf2[8] ^= 0x02;
546 
547  ret.Set (buf2);
548  return ret;
549 }
550 
552 {
553  NS_LOG_FUNCTION (addr);
554  Ipv6Address ret;
555  uint8_t buf[8];
556  uint8_t buf2[16];
557 
558  addr.CopyTo (buf);
559 
560  memset (buf2, 0x00, sizeof (buf2));
561  buf2[0] = 0xfe;
562  buf2[1] = 0x80;
563  memcpy (buf2 + 8, buf, 8);
564 
565  ret.Set (buf2);
566  return ret;
567 }
568 
570 {
571  NS_LOG_FUNCTION (addr);
572  Ipv6Address ret;
573  uint8_t buf[2];
574  uint8_t buf2[16];
575 
576  buf[0] = 0;
577  addr.CopyTo (&buf[1]);
578 
579  memset (buf2, 0x00, sizeof (buf2));
580  buf2[0] = 0xfe;
581  buf2[1] = 0x80;
582  memcpy (buf2 + 14, buf, 2);
583  buf2[11] = 0xff;
584  buf2[12] = 0xfe;
585 
586  ret.Set (buf2);
587  return ret;
588 }
589 
591 {
592  NS_LOG_FUNCTION (addr);
593  uint8_t buf[16];
594  uint8_t buf2[16];
595  Ipv6Address ret;
596 
597  addr.Serialize (buf2);
598 
599  memset (buf, 0x00, sizeof (buf));
600  buf[0] = 0xff;
601  buf[1] = 0x02;
602  buf[11] = 0x01;
603  buf[12] = 0xff;
604  buf[13] = buf2[13];
605  buf[14] = buf2[14];
606  buf[15] = buf2[15];
607 
608  ret.Set (buf);
609  return ret;
610 }
611 
612 void Ipv6Address::Print (std::ostream& os) const
613 {
614  NS_LOG_FUNCTION (this << &os);
615 
616  // note: part of this function has been adapted from inet_ntop6 Linux function.
617  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
618  // Author: Paul Vixie, 1996.
619 
620  if (IsIpv4MappedAddress ())
621  {
622  os << "::ffff:"
623  << (unsigned int) m_address[12] << "."
624  << (unsigned int) m_address[13] << "."
625  << (unsigned int) m_address[14] << "."
626  << (unsigned int) m_address[15];
627  return;
628  }
629 
630  uint16_t address[8];
631  uint8_t i;
632 
633  for (i=0; i<8; i++)
634  {
635  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
636  }
637 
638  int8_t bestBase = -1;
639  int8_t bestLen = 0;
640  int8_t curBase = -1;
641  int8_t curLen = 0;
642 
643  for (i=0; i<8; i++)
644  {
645  if (address[i] == 0)
646  {
647  if (curBase == -1)
648  {
649  curBase = i;
650  curLen = 1;
651  }
652  else
653  {
654  curLen++;
655  }
656  }
657  else
658  {
659  if (curBase != -1)
660  {
661  if (bestBase == -1 || curLen > bestLen)
662  {
663  bestBase = curBase;
664  bestLen = curLen;
665  }
666  curBase = -1;
667  }
668  }
669  }
670  if (curBase != -1)
671  {
672  if (bestBase == -1 || curLen > bestLen)
673  {
674  bestBase = curBase;
675  bestLen = curLen;
676  }
677  }
678  if (bestBase != -1 && bestLen < 2)
679  {
680  bestBase = -1;
681  }
682 
683  for (i = 0; i < 8;) {
684  // Are we inside the best run of 0x00's?
685  if (i == bestBase)
686  {
687  os << ':';
688  i += bestLen;
689  continue;
690  }
691  // Are we following an initial run of 0x00s or any real hex?
692  if (i != 0)
693  {
694  os << ':';
695  }
696  os << std::hex << (unsigned int) address[i];
697  i++;
698  }
699  // Was it a trailing run of 0x00's?
700  if (bestBase != -1 && (bestBase + bestLen) == 8)
701  {
702  os << ':';
703  }
704  os << std::dec;
705 }
706 
708 {
709  NS_LOG_FUNCTION (this);
710  static Ipv6Address localhost ("::1");
711  return (*this == localhost);
712 }
713 
715 {
716  NS_LOG_FUNCTION (this);
717  if (m_address[0] == 0xff)
718  {
719  return true;
720  }
721  return false;
722 }
723 
725 {
726  NS_LOG_FUNCTION (this);
727  if (m_address[0] == 0xff && m_address[1] == 0x02)
728  {
729  return true;
730  }
731  return false;
732 }
733 
735 {
736  NS_LOG_FUNCTION (this);
737  static uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738  0x00, 0x00, 0xff, 0xff };
739  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
740  {
741  return (true);
742  }
743  return (false);
744 }
745 
747 {
748  NS_LOG_FUNCTION (this << prefix);
749  Ipv6Address ipv6;
750  uint8_t addr[16];
751  uint8_t pref[16];
752  unsigned int i = 0;
753 
754  memcpy (addr, m_address, 16);
755  ((Ipv6Prefix)prefix).GetBytes (pref);
756 
757  /* a little bit ugly... */
758  for (i = 0; i < 16; i++)
759  {
760  addr[i] = addr[i] & pref[i];
761  }
762  ipv6.Set (addr);
763  return ipv6;
764 }
765 
767 {
768  NS_LOG_FUNCTION (this);
769 
770  static Ipv6Address documentation ("ff02::1:ff00:0");
771  if (CombinePrefix (Ipv6Prefix (104)) == documentation)
772  {
773  return true;
774  }
775  return false;
776 }
777 
779 {
780  NS_LOG_FUNCTION (this);
781  static Ipv6Address allNodesI ("ff01::1");
782  static Ipv6Address allNodesL ("ff02::1");
783  static Ipv6Address allNodesR ("ff03::1");
784  return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
785 }
786 
788 {
789  NS_LOG_FUNCTION (this);
790  static Ipv6Address allroutersI ("ff01::2");
791  static Ipv6Address allroutersL ("ff02::2");
792  static Ipv6Address allroutersR ("ff03::2");
793  static Ipv6Address allroutersS ("ff05::2");
794  return (*this == allroutersI || *this == allroutersL || *this == allroutersR || *this == allroutersS);
795 }
796 
797 bool Ipv6Address::IsAny () const
798 {
799  NS_LOG_FUNCTION (this);
800  static Ipv6Address any ("::");
801  return (*this == any);
802 }
803 
804 
806 {
807  NS_LOG_FUNCTION (this);
808  static Ipv6Address documentation ("2001:db8::0");
809  if (CombinePrefix (Ipv6Prefix (32)) == documentation)
810  {
811  return true;
812  }
813  return false;
814 }
815 
816 bool Ipv6Address::HasPrefix (Ipv6Prefix const& prefix) const
817 {
818  NS_LOG_FUNCTION (this << prefix);
819 
820  Ipv6Address masked = CombinePrefix (prefix);
822 
823  return (masked == reference);
824 }
825 
826 
828 {
830  return address.CheckCompatible (GetType (), 16);
831 }
832 
833 Ipv6Address::operator Address () const
834 {
835  return ConvertTo ();
836 }
837 
839 {
840  NS_LOG_FUNCTION (this);
841  uint8_t buf[16];
842  Serialize (buf);
843  return Address (GetType (), buf, 16);
844 }
845 
847 {
849  NS_ASSERT (address.CheckCompatible (GetType (), 16));
850  uint8_t buf[16];
851  address.CopyTo (buf);
852  return Deserialize (buf);
853 }
854 
855 uint8_t Ipv6Address::GetType (void)
856 {
858  static uint8_t type = Address::Register ();
859  return type;
860 }
861 
863 {
865  static Ipv6Address nmc ("ff02::1");
866  return nmc;
867 }
868 
870 {
872  static Ipv6Address rmc ("ff02::2");
873  return rmc;
874 }
875 
877 {
879  static Ipv6Address hmc ("ff02::3");
880  return hmc;
881 }
882 
884 {
886  static Ipv6Address loopback ("::1");
887  return loopback;
888 }
889 
891 {
893  static Ipv6Address zero ("::");
894  return zero;
895 }
896 
898 {
900  static Ipv6Address any ("::");
901  return any;
902 }
903 
905 {
907  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
908  return ones;
909 }
910 
911 void Ipv6Address::GetBytes (uint8_t buf[16]) const
912 {
913  NS_LOG_FUNCTION (this << &buf);
914  memcpy (buf, m_address, 16);
915 }
916 
918 {
919  NS_LOG_FUNCTION (this);
920  static Ipv6Address linkLocal ("fe80::0");
921  if (CombinePrefix (Ipv6Prefix (64)) == linkLocal)
922  {
923  return true;
924  }
925  return false;
926 }
927 
928 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
929 {
930  NS_LOG_FUNCTION (this << other);
931  if (!memcmp (m_address, other.m_address, 16))
932  {
933  return true;
934  }
935  return false;
936 }
937 
938 bool Ipv6Address::IsInitialized (void) const
939 {
940  NS_LOG_FUNCTION (this);
941  return (m_initialized);
942 }
943 
944 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
945 {
946  address.Print (os);
947  return os;
948 }
949 
950 std::istream& operator >> (std::istream& is, Ipv6Address& address)
951 {
952  std::string str;
953  is >> str;
954  address = Ipv6Address (str.c_str ());
955  return is;
956 }
957 
959 {
960  NS_LOG_FUNCTION (this);
961  memset (m_prefix, 0x00, 16);
962  m_prefixLength = 64;
963 }
964 
965 Ipv6Prefix::Ipv6Prefix (char const* prefix)
966 {
967  NS_LOG_FUNCTION (this << prefix);
968  AsciiToIpv6Host (prefix, m_prefix);
970 }
971 
972 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
973 {
974  NS_LOG_FUNCTION (this << &prefix);
975  memcpy (m_prefix, prefix, 16);
977 }
978 
979 Ipv6Prefix::Ipv6Prefix (char const* prefix, uint8_t prefixLength)
980 {
981  NS_LOG_FUNCTION (this << prefix);
982  AsciiToIpv6Host (prefix, m_prefix);
983 
984  uint8_t autoLength = GetMinimumPrefixLength ();
985  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
986 
987  m_prefixLength = prefixLength;
988 }
989 
990 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16], uint8_t prefixLength)
991 {
992  NS_LOG_FUNCTION (this << &prefix);
993  memcpy (m_prefix, prefix, 16);
994 
995  uint8_t autoLength = GetMinimumPrefixLength ();
996  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
997 
998  m_prefixLength = prefixLength;
999 }
1000 
1001 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
1002 {
1003  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
1004  unsigned int nb=0;
1005  unsigned int mod=0;
1006  unsigned int i=0;
1007 
1008  memset (m_prefix, 0x00, 16);
1009  m_prefixLength = prefix;
1010 
1011  NS_ASSERT (prefix <= 128);
1012 
1013  nb = prefix / 8;
1014  mod = prefix % 8;
1015 
1016  // protect memset with 'nb > 0' check to suppress
1017  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
1018  if (nb > 0)
1019  {
1020  memset (m_prefix, 0xff, nb);
1021  }
1022  if (mod)
1023  {
1024  m_prefix[nb] = 0xff << (8-mod);
1025  }
1026 
1027  if (nb < 16)
1028  {
1029  nb++;
1030  for (i = nb; i < 16; i++)
1031  {
1032  m_prefix[i] = 0x00;
1033  }
1034  }
1035 }
1036 
1038 {
1039  memcpy (m_prefix, prefix.m_prefix, 16);
1040  m_prefixLength = prefix.m_prefixLength;
1041 }
1042 
1044 {
1045  memcpy (m_prefix, prefix->m_prefix, 16);
1046  m_prefixLength = prefix->m_prefixLength;
1047 }
1048 
1050 {
1051  /* do nothing */
1052  NS_LOG_FUNCTION (this);
1053 }
1054 
1056 {
1057  NS_LOG_FUNCTION (this << a << b);
1058  uint8_t addrA[16];
1059  uint8_t addrB[16];
1060  unsigned int i = 0;
1061 
1062  a.GetBytes (addrA);
1063  b.GetBytes (addrB);
1064 
1065  /* a little bit ugly... */
1066  for (i = 0; i < 16; i++)
1067  {
1068  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
1069  {
1070  return false;
1071  }
1072  }
1073  return true;
1074 }
1075 
1076 void Ipv6Prefix::Print (std::ostream &os) const
1077 {
1078  NS_LOG_FUNCTION (this << &os);
1079 
1080  os << "/" << (unsigned int) GetPrefixLength();
1081 }
1082 
1084 {
1086  static Ipv6Prefix prefix ((uint8_t)128);
1087  return prefix;
1088 }
1089 
1091 {
1093  static Ipv6Prefix ones ((uint8_t)128);
1094  return ones;
1095 }
1096 
1098 {
1100  static Ipv6Prefix prefix ((uint8_t)0);
1101  return prefix;
1102 }
1103 
1104 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
1105 {
1106  NS_LOG_FUNCTION (this << &buf);
1107  memcpy (buf, m_prefix, 16);
1108 }
1109 
1111 {
1112  uint8_t prefixBytes[16];
1113  memcpy (prefixBytes, m_prefix, 16);
1114 
1115  Ipv6Address convertedPrefix = Ipv6Address (prefixBytes);
1116  return convertedPrefix;
1117 }
1118 
1120 {
1121  NS_LOG_FUNCTION (this);
1122  return m_prefixLength;
1123 }
1124 
1125 void Ipv6Prefix::SetPrefixLength (uint8_t prefixLength)
1126 {
1127  NS_LOG_FUNCTION (this);
1128  m_prefixLength = prefixLength;
1129 }
1130 
1132 {
1133  NS_LOG_FUNCTION (this);
1134 
1135  uint8_t prefixLength = 0;
1136  bool stop = false;
1137 
1138  for(int8_t i=15; i>=0 && !stop; i--)
1139  {
1140  uint8_t mask = m_prefix[i];
1141 
1142  for(uint8_t j=0; j<8 && !stop; j++)
1143  {
1144  if ((mask & 1) == 0)
1145  {
1146  mask = mask >> 1;
1147  prefixLength++;
1148  }
1149  else
1150  {
1151  stop = true;
1152  }
1153  }
1154  }
1155 
1156  return 128 - prefixLength;
1157 }
1158 
1159 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
1160 {
1161  if (!memcmp (m_prefix, other.m_prefix, 16))
1162  {
1163  return true;
1164  }
1165  return false;
1166 }
1167 
1168 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1169 {
1170  prefix.Print (os);
1171  return os;
1172 }
1173 
1174 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1175 {
1176  std::string str;
1177  is >> str;
1178  prefix = Ipv6Prefix (str.c_str ());
1179  return is;
1180 }
1181 
1183 {
1184  uint8_t buf[16];
1185 
1186  x.GetBytes (buf);
1187 
1188  return lookuphash (buf, sizeof (buf), 0);
1189 }
1190 
1193 
1194 } /* namespace ns3 */
1195 
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.
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:428
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.
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:160
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:616
size_t operator()(Ipv6Address const &x) const
Returns the hash of an 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
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:137
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.
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:611
static bool AsciiToIpv6Host(const char *address, uint8_t addr[16])
Convert an IPv6 C-string into a 128-bit representation.
Ipv6Address ConvertToIpv6Address() const
Convert the Prefix into an IPv6 Address.
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:429
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:466
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.