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::IsInitialized (void) const
929 {
930  NS_LOG_FUNCTION (this);
931  return (m_initialized);
932 }
933 
934 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
935 {
936  address.Print (os);
937  return os;
938 }
939 
940 std::istream& operator >> (std::istream& is, Ipv6Address& address)
941 {
942  std::string str;
943  is >> str;
944  address = Ipv6Address (str.c_str ());
945  return is;
946 }
947 
949 {
950  NS_LOG_FUNCTION (this);
951  memset (m_prefix, 0x00, 16);
952  m_prefixLength = 64;
953 }
954 
955 Ipv6Prefix::Ipv6Prefix (char const* prefix)
956 {
957  NS_LOG_FUNCTION (this << prefix);
958  AsciiToIpv6Host (prefix, m_prefix);
960 }
961 
962 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
963 {
964  NS_LOG_FUNCTION (this << &prefix);
965  memcpy (m_prefix, prefix, 16);
967 }
968 
969 Ipv6Prefix::Ipv6Prefix (char const* prefix, uint8_t prefixLength)
970 {
971  NS_LOG_FUNCTION (this << prefix);
972  AsciiToIpv6Host (prefix, m_prefix);
973 
974  uint8_t autoLength = GetMinimumPrefixLength ();
975  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
976 
977  m_prefixLength = prefixLength;
978 }
979 
980 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16], uint8_t prefixLength)
981 {
982  NS_LOG_FUNCTION (this << &prefix);
983  memcpy (m_prefix, prefix, 16);
984 
985  uint8_t autoLength = GetMinimumPrefixLength ();
986  NS_ASSERT_MSG (autoLength <= prefixLength, "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address (prefix) << "/" << +prefixLength);
987 
988  m_prefixLength = prefixLength;
989 }
990 
991 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
992 {
993  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
994  unsigned int nb=0;
995  unsigned int mod=0;
996  unsigned int i=0;
997 
998  memset (m_prefix, 0x00, 16);
999  m_prefixLength = prefix;
1000 
1001  NS_ASSERT (prefix <= 128);
1002 
1003  nb = prefix / 8;
1004  mod = prefix % 8;
1005 
1006  // protect memset with 'nb > 0' check to suppress
1007  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
1008  if (nb > 0)
1009  {
1010  memset (m_prefix, 0xff, nb);
1011  }
1012  if (mod)
1013  {
1014  m_prefix[nb] = 0xff << (8-mod);
1015  }
1016 
1017  if (nb < 16)
1018  {
1019  nb++;
1020  for (i = nb; i < 16; i++)
1021  {
1022  m_prefix[i] = 0x00;
1023  }
1024  }
1025 }
1026 
1028 {
1029  memcpy (m_prefix, prefix.m_prefix, 16);
1030  m_prefixLength = prefix.m_prefixLength;
1031 }
1032 
1034 {
1035  memcpy (m_prefix, prefix->m_prefix, 16);
1036  m_prefixLength = prefix->m_prefixLength;
1037 }
1038 
1040 {
1041  /* do nothing */
1042  NS_LOG_FUNCTION (this);
1043 }
1044 
1046 {
1047  NS_LOG_FUNCTION (this << a << b);
1048  uint8_t addrA[16];
1049  uint8_t addrB[16];
1050  unsigned int i = 0;
1051 
1052  a.GetBytes (addrA);
1053  b.GetBytes (addrB);
1054 
1055  /* a little bit ugly... */
1056  for (i = 0; i < 16; i++)
1057  {
1058  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
1059  {
1060  return false;
1061  }
1062  }
1063  return true;
1064 }
1065 
1066 void Ipv6Prefix::Print (std::ostream &os) const
1067 {
1068  NS_LOG_FUNCTION (this << &os);
1069 
1070  os << "/" << (unsigned int) GetPrefixLength();
1071 }
1072 
1074 {
1076  static Ipv6Prefix prefix ((uint8_t)128);
1077  return prefix;
1078 }
1079 
1081 {
1083  static Ipv6Prefix ones ((uint8_t)128);
1084  return ones;
1085 }
1086 
1088 {
1090  static Ipv6Prefix prefix ((uint8_t)0);
1091  return prefix;
1092 }
1093 
1094 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
1095 {
1096  NS_LOG_FUNCTION (this << &buf);
1097  memcpy (buf, m_prefix, 16);
1098 }
1099 
1101 {
1102  uint8_t prefixBytes[16];
1103  memcpy (prefixBytes, m_prefix, 16);
1104 
1105  Ipv6Address convertedPrefix = Ipv6Address (prefixBytes);
1106  return convertedPrefix;
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 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1150 {
1151  prefix.Print (os);
1152  return os;
1153 }
1154 
1155 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1156 {
1157  std::string str;
1158  is >> str;
1159  prefix = Ipv6Prefix (str.c_str ());
1160  return is;
1161 }
1162 
1164 {
1165  uint8_t buf[16];
1166 
1167  x.GetBytes (buf);
1168 
1169  return lookuphash (buf, sizeof (buf), 0);
1170 }
1171 
1174 
1175 } /* namespace ns3 */
1176 
a polymophic address class
Definition: address.h:91
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:41
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
static Ipv4Address Deserialize(const uint8_t buf[4])
size_t operator()(Ipv6Address const &x) const
Returns the hash of an IPv6 address.
Describes an IPv6 address.
Definition: ipv6-address.h:50
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
void Print(std::ostream &os) const
Print this address to the given output stream.
Address ConvertTo(void) const
convert the IPv6Address object to an Address object.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix) const
Combine this address with a prefix.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
static Ipv6Address GetAllHostsMulticast()
Get the "all hosts multicast" address.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
static Ipv6Address Deserialize(const uint8_t buf[16])
Deserialize this address.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address from a Mac address.
~Ipv6Address()
Destructor.
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
void Set(char const *address)
Sets an Ipv6Address by parsing the input C-string.
Ipv6Address()
Default constructor.
bool IsInitialized(void) const
bool IsAny() const
If the IPv6 address is the "Any" address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
bool m_initialized
IPv6 address has been explicitly initialized to a valid value.
Definition: ipv6-address.h:418
uint8_t m_address[16]
The address representation on 128 bits (16 bytes).
Definition: ipv6-address.h:417
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
static Ipv6Address GetOnes()
Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Address mac)
Make the autoconfigured link-local IPv6 address from a Mac address.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
bool HasPrefix(Ipv6Prefix const &prefix) const
Compares an address and a prefix.
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
static uint8_t GetType(void)
Return the Type of address.
static Ipv6Address GetLoopback()
Get the loopback address.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
Describes an IPv6 prefix.
Definition: ipv6-address.h:456
uint8_t m_prefixLength
The prefix length.
Definition: ipv6-address.h:594
static Ipv6Prefix GetLoopback()
Get the loopback prefix ( /128).
~Ipv6Prefix()
Destructor.
uint8_t m_prefix[16]
The prefix representation.
Definition: ipv6-address.h:589
void Print(std::ostream &os) const
Print this address to the given output stream.
uint8_t GetPrefixLength() const
Get prefix length.
Ipv6Address ConvertToIpv6Address() const
Convert the Prefix into an IPv6 Address.
static Ipv6Prefix GetZero()
Get the zero prefix ( /0).
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
void SetPrefixLength(uint8_t prefixLength)
Set prefix length.
Ipv6Prefix()
Default constructor.
uint8_t GetMinimumPrefixLength() const
Get the minimum prefix length, i.e., 128 - the length of the largest sequence trailing zeroes.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
This class can contain 16 bit addresses.
Definition: mac16-address.h:42
static bool IsMatchingType(const Address &address)
static Mac16Address ConvertFrom(const Address &address)
void CopyTo(uint8_t buffer[2]) const
an EUI-48 address
Definition: mac48-address.h:44
static bool IsMatchingType(const Address &address)
static Mac48Address ConvertFrom(const Address &address)
void CopyTo(uint8_t buffer[6]) const
an EUI-64 address
Definition: mac64-address.h:44
static bool IsMatchingType(const Address &address)
void CopyTo(uint8_t buffer[8]) const
static Mac64Address ConvertFrom(const Address &address)
A class used for addressing MAC8 MAC's.
Definition: mac8-address.h:43
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:54
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
Definition: mac8-address.cc:63
void CopyTo(uint8_t *pBuffer) const
Writes address to buffer parameter.
Definition: mac8-address.cc:80
static double zero
#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
#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
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:50
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:205
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define mix(a, b, c)
address
Definition: first.py:44
Every class exported by the ns3 library is enclosed in the ns3 namespace.
ATTRIBUTE_HELPER_CPP(Length)
static uint32_t lookuphash(unsigned char *k, uint32_t length, uint32_t level)
Get a hash key.
Definition: ipv6-address.cc:72
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
static bool AsciiToIpv6Host(const char *address, uint8_t addr[16])
Convert an IPv6 C-string into a 128-bit representation.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
list x
Random number samples.