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
55namespace ns3 {
56
57NS_LOG_COMPONENT_DEFINE ("Ipv6Address");
58
59#ifdef __cplusplus
60extern "C"
61{ /* } */
62#endif
63
72static 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
150static 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
323void Ipv6Address::Set (char const* address)
324{
325 NS_LOG_FUNCTION (this << address);
327 m_initialized = true;
328}
329
330void 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
338void Ipv6Address::Serialize (uint8_t buf[16]) const
339{
340 NS_LOG_FUNCTION (this << &buf);
341 memcpy (buf, m_address, 16);
342}
343
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
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
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
612void 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
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
816bool 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
833Ipv6Address::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
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
911void 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
929{
930 NS_LOG_FUNCTION (this);
931 return (m_initialized);
932}
933
934std::ostream& operator << (std::ostream& os, Ipv6Address const& address)
935{
936 address.Print (os);
937 return os;
938}
939
940std::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
955Ipv6Prefix::Ipv6Prefix (char const* prefix)
956{
957 NS_LOG_FUNCTION (this << prefix);
958 AsciiToIpv6Host (prefix, m_prefix);
960}
961
962Ipv6Prefix::Ipv6Prefix (uint8_t prefix[16])
963{
964 NS_LOG_FUNCTION (this << &prefix);
965 memcpy (m_prefix, prefix, 16);
967}
968
969Ipv6Prefix::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
980Ipv6Prefix::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
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);
1031}
1032
1034{
1035 memcpy (m_prefix, prefix->m_prefix, 16);
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
1066void 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
1094void 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
1115void 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
1149std::ostream& operator << (std::ostream& os, Ipv6Prefix const& prefix)
1150{
1151 prefix.Print (os);
1152 return os;
1153}
1154
1155std::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.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition: angles.cc:139
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:162
static uint32_t lookuphash(unsigned char *k, uint32_t length, uint32_t level)
Get a hash key.
Definition: ipv6-address.cc:72
static bool AsciiToIpv6Host(const char *address, uint8_t addr[16])
Convert an IPv6 C-string into a 128-bit representation.
list x
Random number samples.