A Discrete-Event Network Simulator
API
ipv6-address.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007-2008 Louis Pasteur University
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
19  */
20 
21 // Part of the Ipv6Address::Print function has been adapted from inet_ntop6 Linux function.
22 // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
23 // Author: Paul Vixie, 1996.
24 // The inet_ntop6 function was under the copyright below, which is
25 // compatible with GPLv2, see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses.
26 
27 /* Copyright (c) 1996 by Internet Software Consortium.
28  *
29  * Permission to use, copy, modify, and distribute this software for any
30  * purpose with or without fee is hereby granted, provided that the above
31  * copyright notice and this permission notice appear in all copies.
32  *
33  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
34  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
35  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
36  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
37  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
38  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
39  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
40  * SOFTWARE.
41  */
42 
43 
44 #include <iomanip>
45 #include <memory.h>
46 
47 #include "ns3/log.h"
48 #include "ns3/assert.h"
49 
50 #include "mac16-address.h"
51 #include "mac48-address.h"
52 #include "mac64-address.h"
53 #include "ipv6-address.h"
54 
55 namespace ns3 {
56 
57 NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
58 
59 #ifdef __cplusplus
60 extern "C"
61 { /* } */
62 #endif
63 
72 static uint32_t lookuphash (unsigned char* k, uint32_t length, uint32_t level)
73 {
74  NS_LOG_FUNCTION (k << length << level);
75 #define mix(a, b, c) \
76  ({ \
77  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 13); \
78  (b) -= (c); (b) -= (a); (b) ^= ((a) << 8); \
79  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 13); \
80  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 12); \
81  (b) -= (c); (b) -= (a); (b) ^= ((a) << 16); \
82  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 5); \
83  (a) -= (b); (a) -= (c); (a) ^= ((c) >> 3); \
84  (b) -= (c); (b) -= (a); (b) ^= ((a) << 10); \
85  (c) -= (a); (c) -= (b); (c) ^= ((b) >> 15); \
86  })
87 
88  typedef uint32_t ub4; /* unsigned 4-byte quantities */
89  uint32_t a = 0;
90  uint32_t b = 0;
91  uint32_t c = 0;
92  uint32_t len = 0;
93 
94  /* Set up the internal state */
95  len = length;
96  a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
97  c = level; /* the previous hash value */
98 
99  /* handle most of the key */
100  while (len >= 12)
101  {
102  a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24));
103  b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24));
104  c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24));
105  mix (a, b, c);
106  k += 12;
107  len -= 12;
108  }
109 
110  /* handle the last 11 bytes */
111  c += length;
112  switch (len) /* all the case statements fall through */
113  {
114  case 11: c += ((ub4)k[10] << 24);
115  case 10: c += ((ub4)k[9] << 16);
116  case 9: c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */
117  case 8: b += ((ub4)k[7] << 24);
118  case 7: b += ((ub4)k[6] << 16);
119  case 6: b += ((ub4)k[5] << 8);
120  case 5: b += k[4];
121  case 4: a += ((ub4)k[3] << 24);
122  case 3: a += ((ub4)k[2] << 16);
123  case 2: a += ((ub4)k[1] << 8);
124  case 1: a += k[0];
125  /* case 0: nothing left to add */
126  }
127  mix (a, b, c);
128 
129 #undef mix
130 
131  /* report the result */
132  return c;
133 }
134 
135 #ifdef __cplusplus
136 }
137 #endif
138 
150 static bool AsciiToIpv6Host (const char *address, uint8_t addr[16])
151 {
152  NS_LOG_FUNCTION (address << &addr);
153  static const char xdigits_l[] = "0123456789abcdef";
154  static const char xdigits_u[] = "0123456789ABCDEF";
155  unsigned char tmp[16];
156  unsigned char* tp = tmp;
157  unsigned char* const endp = tp + 16;
158  unsigned char* colonp = 0;
159  const char* xdigits = 0;
160 #if 0
161  const char* curtok = 0;
162 #endif
163  int ch = 0;
164  int seen_xdigits = 0;
165  unsigned int val = 0;
166 
167  memset (tp, 0x00, 16);
168 
169  /* Leading :: requires some special handling. */
170  if (*address == ':')
171  {
172  if (*++address != ':')
173  {
174  return (0);
175  }
176  }
177 #if 0
178  curtok = address;
179 #endif
180  while ((ch = *address++) != '\0')
181  {
182  const char *pch = 0;
183 
184  if ((pch = strchr ((xdigits = xdigits_l), ch)) == 0)
185  {
186  pch = strchr ((xdigits = xdigits_u), ch);
187  }
188 
189  if (pch != 0)
190  {
191  val <<= 4;
192  val |= (pch - xdigits);
193 
194  if (++seen_xdigits > 4)
195  {
196  return (0);
197  }
198  continue;
199  }
200  if (ch == ':')
201  {
202 #if 0
203  curtok = address;
204 #endif
205 
206  if (!seen_xdigits)
207  {
208  if (colonp)
209  return (0);
210  colonp = tp;
211  continue;
212  }
213 
214  if (endp - tp < 2)
215  {
216  return (0);
217  }
218 
219  *tp++ = (unsigned char)(val >> 8) & 0xff;
220  *tp++ = (unsigned char) val & 0xff;
221  seen_xdigits = 0;
222  val = 0;
223  continue;
224  }
225 
226  /* \todo Handle IPv4 mapped address (2001::192.168.0.1) */
227 #if 0
228  if (ch == '.' && (endp - tp > 3 /* NS_INADDRSZ - 1 */)) &&
229  inet_pton4 (curtok, tp) > 0)
230  {
231  tp += 4 /*NS_INADDRSZ*/;
232  seen_xdigits = 0;
233  break; /* '\0' was seen by inet_pton4(). */
234  }
235 #endif
236  return (0);
237  }
238 
239  if (seen_xdigits)
240  {
241  if ( endp - tp < 2)
242  {
243  return (0);
244  }
245  *tp++ = (unsigned char)(val >> 8) & 0xff;
246  *tp++ = (unsigned char) val & 0xff;
247  }
248 
249  if (colonp != 0)
250  {
251  /*
252  * Since some memmove ()'s erroneously fail to handle
253  * overlapping regions, we'll do the shift by hand.
254  */
255  const int n = tp - colonp;
256  int i = 0;
257 
258  if (tp == endp)
259  {
260  return (0);
261  }
262 
263  for (i = 1; i <= n; i++)
264  {
265  endp[-i] = colonp[n - i];
266  colonp[n - i] = 0;
267  }
268 
269  tp = endp;
270  }
271 
272  if (tp != endp)
273  {
274  return (0);
275  }
276 
277  memcpy (addr, tmp, 16);
278  return (1);
279 }
280 
282 {
283  NS_LOG_FUNCTION (this);
284  memset (m_address, 0x00, 16);
285 }
286 
288 {
289  // Do not add function logging here, to avoid stack overflow
290  memcpy (m_address, addr.m_address, 16);
291 }
292 
294 {
295  // Do not add function logging here, to avoid stack overflow
296  memcpy (m_address, addr->m_address, 16);
297 }
298 
300 {
301  NS_LOG_FUNCTION (this << address);
302  AsciiToIpv6Host (address, m_address);
303 }
304 
306 {
307  NS_LOG_FUNCTION (this << &address);
308  /* 128 bit => 16 bytes */
309  memcpy (m_address, address, 16);
310 }
311 
313 {
314  /* do nothing */
315  NS_LOG_FUNCTION (this);
316 }
317 
318 void Ipv6Address::Set (char const* address)
319 {
320  NS_LOG_FUNCTION (this << address);
321  AsciiToIpv6Host (address, m_address);
322 }
323 
324 void Ipv6Address::Set (uint8_t address[16])
325 {
326  /* 128 bit => 16 bytes */
327  NS_LOG_FUNCTION (this << &address);
328  memcpy (m_address, address, 16);
329 }
330 
331 void Ipv6Address::Serialize (uint8_t buf[16]) const
332 {
333  NS_LOG_FUNCTION (this << &buf);
334  memcpy (buf, m_address, 16);
335 }
336 
337 Ipv6Address Ipv6Address::Deserialize (const uint8_t buf[16])
338 {
339  NS_LOG_FUNCTION (&buf);
340  Ipv6Address ipv6 ((uint8_t*)buf);
341  return ipv6;
342 }
343 
345 {
346  NS_LOG_FUNCTION (addr);
347  uint8_t buf[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
348  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
349  addr.Serialize (&buf[12]);
350  return (Ipv6Address (buf));
351 }
352 
354 {
355  NS_LOG_FUNCTION (this);
356  uint8_t buf[16];
357  Ipv4Address v4Addr;
358 
359  Serialize (buf);
360  v4Addr = Ipv4Address::Deserialize (&buf[12]);
361  return (v4Addr);
362 }
363 
365 {
366  NS_LOG_FUNCTION (addr << prefix);
367  Ipv6Address ret;
368  uint8_t buf[2];
369  uint8_t buf2[16];
370 
371  addr.CopyTo (buf);
372  prefix.GetBytes (buf2);
373 
374  memcpy (buf2 + 14, buf, 2);
375  buf2[11] = 0xff;
376  buf2[12] = 0xfe;
377 
378  ret.Set (buf2);
379  return ret;
380 }
381 
383 {
384  NS_LOG_FUNCTION (addr << prefix);
385  Ipv6Address ret;
386  uint8_t buf[16];
387  uint8_t buf2[16];
388 
389  addr.CopyTo (buf);
390  prefix.GetBytes (buf2);
391 
392  memcpy (buf2 + 8, buf, 3);
393  buf2[11] = 0xff;
394  buf2[12] = 0xfe;
395  memcpy (buf2 + 13, buf + 3, 3);
396  buf2[8] |= 0x02;
397 
398  ret.Set (buf2);
399  return ret;
400 }
401 
403 {
404  NS_LOG_FUNCTION (addr << prefix);
405  Ipv6Address ret;
406  uint8_t buf[8];
407  uint8_t buf2[16];
408 
409  addr.CopyTo (buf);
410  prefix.GetBytes (buf2);
411 
412  memcpy (buf2 + 8, buf, 8);
413 
414  ret.Set (buf2);
415  return ret;
416 }
417 
419 {
420  NS_LOG_FUNCTION (addr << prefix);
421  Ipv6Address ret;
422  uint8_t buf[2];
423  uint8_t buf2[16];
424 
425  buf[0] = 0;
426  addr.CopyTo (&buf[1]);
427  prefix.GetBytes (buf2);
428 
429  memcpy (buf2 + 14, buf, 2);
430  buf2[11] = 0xff;
431  buf2[12] = 0xfe;
432 
433  ret.Set (buf2);
434  return ret;
435 }
436 
438 {
439  NS_LOG_FUNCTION (addr);
440  Ipv6Address ret;
441  uint8_t buf[2];
442  uint8_t buf2[16];
443 
444  addr.CopyTo (buf);
445 
446  memset (buf2, 0x00, sizeof (buf2));
447  buf2[0] = 0xfe;
448  buf2[1] = 0x80;
449  memcpy (buf2 + 14, buf, 2);
450  buf2[11] = 0xff;
451  buf2[12] = 0xfe;
452 
453  ret.Set (buf2);
454  return ret;
455 }
456 
458 {
459  NS_LOG_FUNCTION (addr);
460  Ipv6Address ret;
461  uint8_t buf[16];
462  uint8_t buf2[16];
463 
464  addr.CopyTo (buf);
465 
466  memset (buf2, 0x00, sizeof (buf2));
467  buf2[0] = 0xfe;
468  buf2[1] = 0x80;
469  memcpy (buf2 + 8, buf, 3);
470  buf2[11] = 0xff;
471  buf2[12] = 0xfe;
472  memcpy (buf2 + 13, buf + 3, 3);
473  buf2[8] |= 0x02;
474 
475  ret.Set (buf2);
476  return ret;
477 }
478 
480 {
481  NS_LOG_FUNCTION (addr);
482  Ipv6Address ret;
483  uint8_t buf[8];
484  uint8_t buf2[16];
485 
486  addr.CopyTo (buf);
487 
488  memset (buf2, 0x00, sizeof (buf2));
489  buf2[0] = 0xfe;
490  buf2[1] = 0x80;
491  memcpy (buf2 + 8, buf, 8);
492 
493  ret.Set (buf2);
494  return ret;
495 }
496 
498 {
499  NS_LOG_FUNCTION (addr);
500  Ipv6Address ret;
501  uint8_t buf[2];
502  uint8_t buf2[16];
503 
504  buf[0] = 0;
505  addr.CopyTo (&buf[1]);
506 
507  memset (buf2, 0x00, sizeof (buf2));
508  buf2[0] = 0xfe;
509  buf2[1] = 0x80;
510  memcpy (buf2 + 14, buf, 2);
511  buf2[11] = 0xff;
512  buf2[12] = 0xfe;
513 
514  ret.Set (buf2);
515  return ret;
516 }
517 
519 {
520  NS_LOG_FUNCTION (addr);
521  uint8_t buf[16];
522  uint8_t buf2[16];
523  Ipv6Address ret;
524 
525  addr.Serialize (buf2);
526 
527  memset (buf, 0x00, sizeof (buf));
528  buf[0] = 0xff;
529  buf[1] = 0x02;
530  buf[11] = 0x01;
531  buf[12] = 0xff;
532  buf[13] = buf2[13];
533  buf[14] = buf2[14];
534  buf[15] = buf2[15];
535 
536  ret.Set (buf);
537  return ret;
538 }
539 
540 void Ipv6Address::Print (std::ostream& os) const
541 {
542  NS_LOG_FUNCTION (this << &os);
543 
544  // note: part of this function has been adapted from inet_ntop6 Linux function.
545  // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
546  // Author: Paul Vixie, 1996.
547 
548  if (IsIpv4MappedAddress ())
549  {
550  os << "::ffff:"
551  << (unsigned int) m_address[12] << "."
552  << (unsigned int) m_address[13] << "."
553  << (unsigned int) m_address[14] << "."
554  << (unsigned int) m_address[15];
555  return;
556  }
557 
558  uint16_t address[8];
559  uint8_t i;
560 
561  for (i=0; i<8; i++)
562  {
563  address[i] = (uint16_t(m_address[2*i]) << 8) | uint16_t(m_address[2*i+1]);
564  }
565 
566  int8_t bestBase = -1;
567  int8_t bestLen = 0;
568  int8_t curBase = -1;
569  int8_t curLen = 0;
570 
571  for (i=0; i<8; i++)
572  {
573  if (address[i] == 0)
574  {
575  if (curBase == -1)
576  {
577  curBase = i;
578  curLen = 1;
579  }
580  else
581  {
582  curLen++;
583  }
584  }
585  else
586  {
587  if (curBase != -1)
588  {
589  if (bestBase == -1 || curLen > bestLen)
590  {
591  bestBase = curBase;
592  bestLen = curLen;
593  }
594  curBase = -1;
595  }
596  }
597  }
598  if (curBase != -1)
599  {
600  if (bestBase == -1 || curLen > bestLen)
601  {
602  bestBase = curBase;
603  bestLen = curLen;
604  }
605  }
606  if (bestBase != -1 && bestLen < 2)
607  {
608  bestBase = -1;
609  }
610 
611  for (i = 0; i < 8;) {
612  // Are we inside the best run of 0x00's?
613  if (i == bestBase)
614  {
615  os << ':';
616  i += bestLen;
617  continue;
618  }
619  // Are we following an initial run of 0x00s or any real hex?
620  if (i != 0)
621  {
622  os << ':';
623  }
624  os << std::hex << (unsigned int) address[i];
625  i++;
626  }
627  // Was it a trailing run of 0x00's?
628  if (bestBase != -1 && (bestBase + bestLen) == 8)
629  {
630  os << ':';
631  }
632  os << std::dec;
633 }
634 
636 {
637  NS_LOG_FUNCTION (this);
638  static Ipv6Address localhost ("::1");
639  return (*this == localhost);
640 }
641 
643 {
644  NS_LOG_FUNCTION (this);
645  if (m_address[0] == 0xff)
646  {
647  return true;
648  }
649  return false;
650 }
651 
653 {
654  NS_LOG_FUNCTION (this);
655  if (m_address[0] == 0xff && m_address[1] == 0x02)
656  {
657  return true;
658  }
659  return false;
660 }
661 
663 {
664  NS_LOG_FUNCTION (this);
665  uint8_t v4MappedPrefix[12] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666  0x00, 0x00, 0xff, 0xff };
667  if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
668  {
669  return (true);
670  }
671  return (false);
672 }
673 
675 {
676  NS_LOG_FUNCTION (this << prefix);
677  Ipv6Address ipv6;
678  uint8_t addr[16];
679  uint8_t pref[16];
680  unsigned int i = 0;
681 
682  memcpy (addr, m_address, 16);
683  ((Ipv6Prefix)prefix).GetBytes (pref);
684 
685  /* a little bit ugly... */
686  for (i = 0; i < 16; i++)
687  {
688  addr[i] = addr[i] & pref[i];
689  }
690  ipv6.Set (addr);
691  return ipv6;
692 }
693 
695 {
696  NS_LOG_FUNCTION (this);
697  uint8_t buf[16];
698 
699  Serialize (buf);
700 
701  if (buf[0] == 0xff &&
702  buf[1] == 0x02 &&
703  buf[11] == 0x01 &&
704  buf[12] == 0xff)
705  {
706  return true;
707  }
708  return false;
709 }
710 
712 {
713  NS_LOG_FUNCTION (this);
714  static Ipv6Address allNodesI ("ff01::1");
715  static Ipv6Address allNodesL ("ff02::1");
716  static Ipv6Address allNodesR ("ff03::1");
717  return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
718 }
719 
721 {
722  NS_LOG_FUNCTION (this);
723  static Ipv6Address allroutersI ("ff01::2");
724  static Ipv6Address allroutersL ("ff02::2");
725  static Ipv6Address allroutersR ("ff03::2");
726  static Ipv6Address allroutersS ("ff05::2");
727  return (*this == allroutersI || *this == allroutersL || *this == allroutersR || *this == allroutersS);
728 }
729 
731 {
732  NS_LOG_FUNCTION (this);
733  static Ipv6Address allhosts ("ff02::3");
734  return (*this == allhosts);
735 }
736 
737 bool Ipv6Address::IsAny () const
738 {
739  NS_LOG_FUNCTION (this);
740  static Ipv6Address any ("::");
741  return (*this == any);
742 }
743 
744 
746 {
747  NS_LOG_FUNCTION (this);
748  Ipv6Address documentation ("2001:db8::0");
749  if (((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (32)) == documentation)
750  {
751  return true;
752  }
753  return false;
754 }
755 
756 
758 {
759  NS_LOG_FUNCTION (address);
760  return address.CheckCompatible (GetType (), 16);
761 }
762 
763 Ipv6Address::operator Address () const
764 {
765  return ConvertTo ();
766 }
767 
769 {
770  NS_LOG_FUNCTION (this);
771  uint8_t buf[16];
772  Serialize (buf);
773  return Address (GetType (), buf, 16);
774 }
775 
777 {
778  NS_LOG_FUNCTION (address);
779  NS_ASSERT (address.CheckCompatible (GetType (), 16));
780  uint8_t buf[16];
781  address.CopyTo (buf);
782  return Deserialize (buf);
783 }
784 
785 uint8_t Ipv6Address::GetType (void)
786 {
788  static uint8_t type = Address::Register ();
789  return type;
790 }
791 
793 {
795  static Ipv6Address nmc ("ff02::1");
796  return nmc;
797 }
798 
800 {
802  static Ipv6Address rmc ("ff02::2");
803  return rmc;
804 }
805 
807 {
809  static Ipv6Address hmc ("ff02::3");
810  return hmc;
811 }
812 
814 {
816  static Ipv6Address loopback ("::1");
817  return loopback;
818 }
819 
821 {
823  static Ipv6Address zero ("::");
824  return zero;
825 }
826 
828 {
830  static Ipv6Address any ("::");
831  return any;
832 }
833 
835 {
837  static Ipv6Address ones ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
838  return ones;
839 }
840 
841 void Ipv6Address::GetBytes (uint8_t buf[16]) const
842 {
843  NS_LOG_FUNCTION (this << &buf);
844  memcpy (buf, m_address, 16);
845 }
846 
848 {
849  NS_LOG_FUNCTION (this);
850  Ipv6Address linkLocal ("fe80::0");
851  if (!IsMulticast () && ((Ipv6Address*)this)->CombinePrefix (Ipv6Prefix (64)) == linkLocal)
852  {
853  return true;
854  }
855  return false;
856 }
857 
858 bool Ipv6Address::IsEqual (const Ipv6Address& other) const
859 {
860  NS_LOG_FUNCTION (this << other);
861  if (!memcmp (m_address, other.m_address, 16))
862  {
863  return true;
864  }
865  return false;
866 }
867 
868 std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
869 {
870  address.Print (os);
871  return os;
872 }
873 
874 std::istream& operator >> (std::istream& is, Ipv6Address& address)
875 {
876  std::string str;
877  is >> str;
878  address = Ipv6Address (str.c_str ());
879  return is;
880 }
881 
883 {
884  NS_LOG_FUNCTION (this);
885  memset (m_prefix, 0x00, 16);
886 }
887 
888 Ipv6Prefix::Ipv6Prefix (char const* prefix)
889 {
890  NS_LOG_FUNCTION (this << prefix);
891  AsciiToIpv6Host (prefix, m_prefix);
892 }
893 
894 Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
895 {
896  NS_LOG_FUNCTION (this << &prefix);
897  memcpy (m_prefix, prefix, 16);
898 }
899 
900 Ipv6Prefix::Ipv6Prefix (uint8_t prefix)
901 {
902  NS_LOG_FUNCTION (this << static_cast<uint32_t> (prefix));
903  unsigned int nb=0;
904  unsigned int mod=0;
905  unsigned int i=0;
906 
907  memset (m_prefix, 0x00, 16);
908 
909  NS_ASSERT (prefix <= 128);
910 
911  nb = prefix / 8;
912  mod = prefix % 8;
913 
914  // protect memset with 'nb > 0' check to suppress
915  // __warn_memset_zero_len compiler errors in some gcc>4.5.x
916  if (nb > 0)
917  {
918  memset (m_prefix, 0xff, nb);
919  }
920  if (mod)
921  {
922  m_prefix[nb] = 0xff << (8-mod);
923  }
924 
925  if (nb < 16)
926  {
927  nb++;
928  for (i = nb; i < 16; i++)
929  {
930  m_prefix[i] = 0x00;
931  }
932  }
933 }
934 
936 {
937  memcpy (m_prefix, prefix.m_prefix, 16);
938 }
939 
941 {
942  memcpy (m_prefix, prefix->m_prefix, 16);
943 }
944 
946 {
947  /* do nothing */
948  NS_LOG_FUNCTION (this);
949 }
950 
952 {
953  NS_LOG_FUNCTION (this << a << b);
954  uint8_t addrA[16];
955  uint8_t addrB[16];
956  unsigned int i = 0;
957 
958  a.GetBytes (addrA);
959  b.GetBytes (addrB);
960 
961  /* a little bit ugly... */
962  for (i = 0; i < 16; i++)
963  {
964  if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
965  {
966  return false;
967  }
968  }
969  return true;
970 }
971 
972 void Ipv6Prefix::Print (std::ostream &os) const
973 {
974  NS_LOG_FUNCTION (this << &os);
975 
976  os << "/" << (unsigned int) GetPrefixLength();
977 }
978 
980 {
982  static Ipv6Prefix prefix ((uint8_t)128);
983  return prefix;
984 }
985 
987 {
989  static Ipv6Prefix ones ((uint8_t)128);
990  return ones;
991 }
992 
994 {
996  static Ipv6Prefix prefix ((uint8_t)0);
997  return prefix;
998 }
999 
1000 void Ipv6Prefix::GetBytes (uint8_t buf[16]) const
1001 {
1002  NS_LOG_FUNCTION (this << &buf);
1003  memcpy (buf, m_prefix, 16);
1004 }
1005 
1007 {
1008  NS_LOG_FUNCTION (this);
1009  uint8_t i = 0;
1010  uint8_t prefixLength = 0;
1011 
1012  for(i = 0; i < 16; i++)
1013  {
1014  uint8_t mask = m_prefix[i];
1015 
1016  while(mask != 0)
1017  {
1018  mask = mask << 1;
1019  prefixLength++;
1020  }
1021  }
1022 
1023  return prefixLength;
1024 }
1025 
1026 bool Ipv6Prefix::IsEqual (const Ipv6Prefix& other) const
1027 {
1028  if (!memcmp (m_prefix, other.m_prefix, 16))
1029  {
1030  return true;
1031  }
1032  return false;
1033 }
1034 
1035 std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1036 {
1037  prefix.Print (os);
1038  return os;
1039 }
1040 
1041 std::istream& operator >> (std::istream& is, Ipv6Prefix& prefix)
1042 {
1043  std::string str;
1044  is >> str;
1045  prefix = Ipv6Prefix (str.c_str ());
1046  return is;
1047 }
1048 
1050 {
1051  uint8_t buf[16];
1052 
1053  x.GetBytes (buf);
1054 
1055  return lookuphash (buf, sizeof (buf), 0);
1056 }
1057 
1060 
1061 } /* namespace ns3 */
1062 
bool IsMatch(Ipv6Address a, Ipv6Address b) const
If the Address match the type.
static bool IsMatchingType(const Address &address)
If the Address matches the type.
bool IsAny() const
If the IPv6 address is the "Any" address.
static Ipv4Address Deserialize(const uint8_t buf[4])
static Ipv6Address GetLoopback()
Get the loopback address.
std::istream & operator>>(std::istream &is, Angles &a)
initialize a struct Angles from input
Definition: angles.cc:48
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
Ipv6Address()
Default constructor.
uint8_t m_address[16]
The address representation on 128 bits (16 bytes).
Definition: ipv6-address.h:391
bool IsLinkLocalMulticast() const
If the IPv6 address is link-local multicast (ff02::/16).
Ipv6Prefix()
Default constructor.
void CopyTo(uint8_t *pBuffer) const
Writes address to buffer parameter.
Definition: mac8-address.cc:80
#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.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
~Ipv6Prefix()
Destructor.
bool IsAllRoutersMulticast() const
If the IPv6 address is "all routers multicast" (ff02::2/8).
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:67
bool IsEqual(const Ipv6Prefix &other) const
Comparison operation between two Ipv6Prefix.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
static Ipv6Address MakeAutoconfiguredAddress(Mac16Address addr, Ipv6Address prefix)
Make the autoconfigured IPv6 address with Mac16Address.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
size_t operator()(Ipv6Address const &x) const
Unary operator to hash IPv6 address.
bool IsEqual(const Ipv6Address &other) const
Comparison operation between two Ipv6Addresses.
bool IsDocumentation() const
If the IPv6 address is a documentation address (2001:DB8::/32).
NS_DEPRECATED bool IsAllHostsMulticast() const
If the IPv6 address is "all hosts multicast" (ff02::3/8).
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
bool IsAllNodesMulticast() const
If the IPv6 address is "all nodes multicast" (ff02::1/8).
static double zero
static Ipv6Prefix GetZero()
Get the zero prefix ( /0).
static uint32_t lookuphash(unsigned char *k, uint32_t length, uint32_t level)
Get a hash key.
Definition: ipv6-address.cc:72
a polymophic address class
Definition: address.h:90
an EUI-64 address
Definition: mac64-address.h:43
bool CheckCompatible(uint8_t type, uint8_t len) const
Definition: address.cc:122
void CopyTo(uint8_t buffer[8]) const
void CopyTo(uint8_t buffer[6]) const
Address ConvertTo(void) const
convert the IPv6Address object to an Address object.
static Ipv6Address GetZero()
Get the 0 (::) Ipv6Address.
A class used for addressing MAC8 MAC&#39;s.
Definition: mac8-address.h:42
void CopyTo(uint8_t buffer[2]) const
void Print(std::ostream &os) const
Print this address to the given output stream.
void Serialize(uint8_t buf[4]) const
Serialize this address to a 4-byte buffer.
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the address.
void Set(char const *address)
Sets an Ipv6Address by parsing the input C-string.
static Ipv6Address GetAllHostsMulticast()
Get the "all hosts multicast" address.
std::ostream & operator<<(std::ostream &os, const Angles &a)
print a struct Angles to output
Definition: angles.cc:42
Every class exported by the ns3 library is enclosed in the ns3 namespace.
address
Definition: first.py:37
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv6Address GetAllNodesMulticast()
Get the "all nodes multicast" address.
an EUI-48 address
Definition: mac48-address.h:43
uint8_t m_prefix[16]
The prefix representation.
Definition: ipv6-address.h:529
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
static Ipv6Address MakeAutoconfiguredLinkLocalAddress(Mac16Address mac)
Make the autoconfigured link-local IPv6 address with Mac16Address.
Describes an IPv6 address.
Definition: ipv6-address.h:49
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:40
void Print(std::ostream &os) const
Print this address to the given output stream.
bool IsSolicitedMulticast() const
If the IPv6 address is a Solicited multicast address.
static Ipv6Prefix GetOnes()
Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
uint32_t CopyTo(uint8_t buffer[MAX_SIZE]) const
Copy the address bytes into a buffer.
Definition: address.cc:82
void GetBytes(uint8_t buf[16]) const
Get the bytes corresponding to the prefix.
~Ipv6Address()
Destructor.
static Ipv6Address GetOnes()
Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
static Ipv6Prefix GetLoopback()
Get the loopback prefix ( /128).
Describes an IPv6 prefix.
Definition: ipv6-address.h:428
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
uint8_t GetPrefixLength() const
Get prefix length.
bool IsLocalhost() const
If the IPv6 address is localhost (::1).
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
Ipv6Address CombinePrefix(Ipv6Prefix const &prefix)
Combine this address with a prefix.
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
static uint8_t Register(void)
Allocate a new type id for a new type of address.
Definition: address.cc:138
static uint8_t GetType(void)
Return the Type of address.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
static Ipv6Address GetAllRoutersMulticast()
Get the "all routers multicast" address.
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.