A Discrete-Event Network Simulator
API
ipv6-address.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007-2008 Louis Pasteur University
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 *
17 * Author: Sebastien Vincent <vincent@clarinet.u-strasbg.fr>
18 */
19
20// Part of the Ipv6Address::Print function has been adapted from inet_ntop6 Linux function.
21// See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
22// Author: Paul Vixie, 1996.
23// The inet_ntop6 function was under the copyright below, which is
24// compatible with GPLv2, see http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses.
25
26/* Copyright (c) 1996 by Internet Software Consortium.
27 *
28 * Permission to use, copy, modify, and distribute this software for any
29 * purpose with or without fee is hereby granted, provided that the above
30 * copyright notice and this permission notice appear in all copies.
31 *
32 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
33 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
34 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
35 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
36 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
37 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
38 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
39 * SOFTWARE.
40 */
41
42#include "ipv6-address.h"
43
44#include "mac16-address.h"
45#include "mac48-address.h"
46#include "mac64-address.h"
47
48#include "ns3/assert.h"
49#include "ns3/log.h"
50
51#include <iomanip>
52#include <memory.h>
53
54namespace ns3
55{
56
57NS_LOG_COMPONENT_DEFINE("Ipv6Address");
58
59#ifdef __cplusplus
60extern "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); \
78 (a) -= (c); \
79 (a) ^= ((c) >> 13); \
80 (b) -= (c); \
81 (b) -= (a); \
82 (b) ^= ((a) << 8); \
83 (c) -= (a); \
84 (c) -= (b); \
85 (c) ^= ((b) >> 13); \
86 (a) -= (b); \
87 (a) -= (c); \
88 (a) ^= ((c) >> 12); \
89 (b) -= (c); \
90 (b) -= (a); \
91 (b) ^= ((a) << 16); \
92 (c) -= (a); \
93 (c) -= (b); \
94 (c) ^= ((b) >> 5); \
95 (a) -= (b); \
96 (a) -= (c); \
97 (a) ^= ((c) >> 3); \
98 (b) -= (c); \
99 (b) -= (a); \
100 (b) ^= ((a) << 10); \
101 (c) -= (a); \
102 (c) -= (b); \
103 (c) ^= ((b) >> 15); \
104 })
105
106 typedef uint32_t ub4; /* unsigned 4-byte quantities */
107 uint32_t a = 0;
108 uint32_t b = 0;
109 uint32_t c = 0;
110 uint32_t len = 0;
111
112 /* Set up the internal state */
113 len = length;
114 a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
115 c = level; /* the previous hash value */
116
117 /* handle most of the key */
118 while (len >= 12)
119 {
120 a += (k[0] + ((ub4)k[1] << 8) + ((ub4)k[2] << 16) + ((ub4)k[3] << 24));
121 b += (k[4] + ((ub4)k[5] << 8) + ((ub4)k[6] << 16) + ((ub4)k[7] << 24));
122 c += (k[8] + ((ub4)k[9] << 8) + ((ub4)k[10] << 16) + ((ub4)k[11] << 24));
123 mix(a, b, c);
124 k += 12;
125 len -= 12;
126 }
127
128 /* handle the last 11 bytes */
129 c += length;
130 switch (len) /* all the case statements fall through */
131 {
132 case 11:
133 c += ((ub4)k[10] << 24);
134 case 10:
135 c += ((ub4)k[9] << 16);
136 case 9:
137 c += ((ub4)k[8] << 8); /* the first byte of c is reserved for the length */
138 case 8:
139 b += ((ub4)k[7] << 24);
140 case 7:
141 b += ((ub4)k[6] << 16);
142 case 6:
143 b += ((ub4)k[5] << 8);
144 case 5:
145 b += k[4];
146 case 4:
147 a += ((ub4)k[3] << 24);
148 case 3:
149 a += ((ub4)k[2] << 16);
150 case 2:
151 a += ((ub4)k[1] << 8);
152 case 1:
153 a += k[0];
154 /* case 0: nothing left to add */
155 }
156 mix(a, b, c);
157
158#undef mix
159
160 /* report the result */
161 return c;
162 }
163
164#ifdef __cplusplus
165}
166#endif
167
179static bool
180AsciiToIpv6Host(const char* address, uint8_t addr[16])
181{
182 NS_LOG_FUNCTION(address << &addr);
183 static const char xdigits_l[] = "0123456789abcdef";
184 static const char xdigits_u[] = "0123456789ABCDEF";
185 unsigned char tmp[16];
186 unsigned char* tp = tmp;
187 unsigned char* const endp = tp + 16;
188 unsigned char* colonp = nullptr;
189 const char* xdigits = nullptr;
190#if 0
191 const char* curtok = 0;
192#endif
193 int ch = 0;
194 int seen_xdigits = 0;
195 unsigned int val = 0;
196
197 memset(tp, 0x00, 16);
198
199 /* Leading :: requires some special handling. */
200 if (*address == ':')
201 {
202 if (*++address != ':')
203 {
204 return (0);
205 }
206 }
207#if 0
208 curtok = address;
209#endif
210 while ((ch = *address++) != '\0')
211 {
212 const char* pch = nullptr;
213
214 if ((pch = strchr((xdigits = xdigits_l), ch)) == nullptr)
215 {
216 pch = strchr((xdigits = xdigits_u), ch);
217 }
218
219 if (pch != nullptr)
220 {
221 val <<= 4;
222 val |= (pch - xdigits);
223
224 if (++seen_xdigits > 4)
225 {
226 return (0);
227 }
228 continue;
229 }
230 if (ch == ':')
231 {
232#if 0
233 curtok = address;
234#endif
235
236 if (!seen_xdigits)
237 {
238 if (colonp)
239 {
240 return (0);
241 }
242 colonp = tp;
243 continue;
244 }
245
246 if (endp - tp < 2)
247 {
248 return (0);
249 }
250
251 *tp++ = (unsigned char)(val >> 8) & 0xff;
252 *tp++ = (unsigned char)val & 0xff;
253 seen_xdigits = 0;
254 val = 0;
255 continue;
256 }
257
258 /* \todo Handle IPv4 mapped address (2001::192.168.0.1) */
259#if 0
260 if (ch == '.' && (endp - tp > 3 /* NS_INADDRSZ - 1 */)) &&
261 inet_pton4 (curtok, tp) > 0)
262 {
263 tp += 4 /*NS_INADDRSZ*/;
264 seen_xdigits = 0;
265 break; /* '\0' was seen by inet_pton4(). */
266 }
267#endif
268 return (0);
269 }
270
271 if (seen_xdigits)
272 {
273 if (endp - tp < 2)
274 {
275 return (0);
276 }
277 *tp++ = (unsigned char)(val >> 8) & 0xff;
278 *tp++ = (unsigned char)val & 0xff;
279 }
280
281 if (colonp != nullptr)
282 {
283 /*
284 * Since some memmove ()'s erroneously fail to handle
285 * overlapping regions, we'll do the shift by hand.
286 */
287 const int n = tp - colonp;
288 int i = 0;
289
290 if (tp == endp)
291 {
292 return (0);
293 }
294
295 for (i = 1; i <= n; i++)
296 {
297 endp[-i] = colonp[n - i];
298 colonp[n - i] = 0;
299 }
300
301 tp = endp;
302 }
303
304 if (tp != endp)
305 {
306 return (0);
307 }
308
309 memcpy(addr, tmp, 16);
310 return (1);
311}
312
314{
315 NS_LOG_FUNCTION(this);
316 memset(m_address, 0x00, 16);
317 m_initialized = false;
318}
319
321{
322 // Do not add function logging here, to avoid stack overflow
323 memcpy(m_address, addr.m_address, 16);
324 m_initialized = true;
325}
326
328{
329 // Do not add function logging here, to avoid stack overflow
330 memcpy(m_address, addr->m_address, 16);
331 m_initialized = true;
332}
333
335{
336 NS_LOG_FUNCTION(this << address);
338 m_initialized = true;
339}
340
342{
343 NS_LOG_FUNCTION(this << &address);
344 /* 128 bit => 16 bytes */
345 memcpy(m_address, address, 16);
346 m_initialized = true;
347}
348
350{
351 /* do nothing */
352 NS_LOG_FUNCTION(this);
353}
354
355void
357{
358 NS_LOG_FUNCTION(this << address);
360 m_initialized = true;
361}
362
363void
365{
366 /* 128 bit => 16 bytes */
367 NS_LOG_FUNCTION(this << &address);
368 memcpy(m_address, address, 16);
369 m_initialized = true;
370}
371
372void
373Ipv6Address::Serialize(uint8_t buf[16]) const
374{
375 NS_LOG_FUNCTION(this << &buf);
376 memcpy(buf, m_address, 16);
377}
378
380Ipv6Address::Deserialize(const uint8_t buf[16])
381{
382 NS_LOG_FUNCTION(&buf);
383 Ipv6Address ipv6((uint8_t*)buf);
384 ipv6.m_initialized = true;
385 return ipv6;
386}
387
390{
391 NS_LOG_FUNCTION(addr);
392 uint8_t buf[16] = {0x00,
393 0x00,
394 0x00,
395 0x00,
396 0x00,
397 0x00,
398 0x00,
399 0x00,
400 0x00,
401 0x00,
402 0xff,
403 0xff,
404 0x00,
405 0x00,
406 0x00,
407 0x00};
408 addr.Serialize(&buf[12]);
409 return (Ipv6Address(buf));
410}
411
414{
415 NS_LOG_FUNCTION(this);
416 uint8_t buf[16];
417 Ipv4Address v4Addr;
418
419 Serialize(buf);
420 v4Addr = Ipv4Address::Deserialize(&buf[12]);
421 return (v4Addr);
422}
423
426{
427 Ipv6Address ipv6Addr = Ipv6Address::GetAny();
428
430 {
432 }
433 else if (Mac48Address::IsMatchingType(addr))
434 {
436 }
437 else if (Mac16Address::IsMatchingType(addr))
438 {
440 }
441 else if (Mac8Address::IsMatchingType(addr))
442 {
444 }
445
446 if (ipv6Addr.IsAny())
447 {
448 NS_ABORT_MSG("Unknown address type");
449 }
450 return ipv6Addr;
451}
452
455{
456 Ipv6Address ipv6PrefixAddr = Ipv6Address::GetOnes().CombinePrefix(prefix);
457 return MakeAutoconfiguredAddress(addr, ipv6PrefixAddr);
458}
459
462{
463 NS_LOG_FUNCTION(addr << prefix);
464 Ipv6Address ret;
465 uint8_t buf[2];
466 uint8_t buf2[16];
467
468 addr.CopyTo(buf);
469 prefix.GetBytes(buf2);
470 memset(buf2 + 8, 0, 8);
471
472 memcpy(buf2 + 14, buf, 2);
473 buf2[11] = 0xff;
474 buf2[12] = 0xfe;
475
476 ret.Set(buf2);
477 return ret;
478}
479
482{
483 NS_LOG_FUNCTION(addr << prefix);
484 Ipv6Address ret;
485 uint8_t buf[16];
486 uint8_t buf2[16];
487
488 addr.CopyTo(buf);
489 prefix.GetBytes(buf2);
490
491 memcpy(buf2 + 8, buf, 3);
492 buf2[11] = 0xff;
493 buf2[12] = 0xfe;
494 memcpy(buf2 + 13, buf + 3, 3);
495 buf2[8] ^= 0x02;
496
497 ret.Set(buf2);
498 return ret;
499}
500
503{
504 NS_LOG_FUNCTION(addr << prefix);
505 Ipv6Address ret;
506 uint8_t buf[8];
507 uint8_t buf2[16];
508
509 addr.CopyTo(buf);
510 prefix.GetBytes(buf2);
511
512 memcpy(buf2 + 8, buf, 8);
513
514 ret.Set(buf2);
515 return ret;
516}
517
520{
521 NS_LOG_FUNCTION(addr << prefix);
522 Ipv6Address ret;
523 uint8_t buf[2];
524 uint8_t buf2[16];
525
526 buf[0] = 0;
527 addr.CopyTo(&buf[1]);
528 prefix.GetBytes(buf2);
529 memset(buf2 + 8, 0, 8);
530
531 memcpy(buf2 + 14, buf, 2);
532 buf2[11] = 0xff;
533 buf2[12] = 0xfe;
534
535 ret.Set(buf2);
536 return ret;
537}
538
541{
542 Ipv6Address ipv6Addr = Ipv6Address::GetAny();
543
545 {
547 }
548 else if (Mac48Address::IsMatchingType(addr))
549 {
551 }
552 else if (Mac16Address::IsMatchingType(addr))
553 {
555 }
556 else if (Mac8Address::IsMatchingType(addr))
557 {
559 }
560
561 if (ipv6Addr.IsAny())
562 {
563 NS_ABORT_MSG("Unknown address type");
564 }
565 return ipv6Addr;
566}
567
570{
571 NS_LOG_FUNCTION(addr);
572 Ipv6Address ret;
573 uint8_t buf[2];
574 uint8_t buf2[16];
575
576 addr.CopyTo(buf);
577
578 memset(buf2, 0x00, sizeof(buf2));
579 buf2[0] = 0xfe;
580 buf2[1] = 0x80;
581 memcpy(buf2 + 14, buf, 2);
582 buf2[11] = 0xff;
583 buf2[12] = 0xfe;
584
585 ret.Set(buf2);
586 return ret;
587}
588
591{
592 NS_LOG_FUNCTION(addr);
593 Ipv6Address ret;
594 uint8_t buf[16];
595 uint8_t buf2[16];
596
597 addr.CopyTo(buf);
598
599 memset(buf2, 0x00, sizeof(buf2));
600 buf2[0] = 0xfe;
601 buf2[1] = 0x80;
602 memcpy(buf2 + 8, buf, 3);
603 buf2[11] = 0xff;
604 buf2[12] = 0xfe;
605 memcpy(buf2 + 13, buf + 3, 3);
606 buf2[8] ^= 0x02;
607
608 ret.Set(buf2);
609 return ret;
610}
611
614{
615 NS_LOG_FUNCTION(addr);
616 Ipv6Address ret;
617 uint8_t buf[8];
618 uint8_t buf2[16];
619
620 addr.CopyTo(buf);
621
622 memset(buf2, 0x00, sizeof(buf2));
623 buf2[0] = 0xfe;
624 buf2[1] = 0x80;
625 memcpy(buf2 + 8, buf, 8);
626
627 ret.Set(buf2);
628 return ret;
629}
630
633{
634 NS_LOG_FUNCTION(addr);
635 Ipv6Address ret;
636 uint8_t buf[2];
637 uint8_t buf2[16];
638
639 buf[0] = 0;
640 addr.CopyTo(&buf[1]);
641
642 memset(buf2, 0x00, sizeof(buf2));
643 buf2[0] = 0xfe;
644 buf2[1] = 0x80;
645 memcpy(buf2 + 14, buf, 2);
646 buf2[11] = 0xff;
647 buf2[12] = 0xfe;
648
649 ret.Set(buf2);
650 return ret;
651}
652
655{
656 NS_LOG_FUNCTION(addr);
657 uint8_t buf[16];
658 uint8_t buf2[16];
659 Ipv6Address ret;
660
661 addr.Serialize(buf2);
662
663 memset(buf, 0x00, sizeof(buf));
664 buf[0] = 0xff;
665 buf[1] = 0x02;
666 buf[11] = 0x01;
667 buf[12] = 0xff;
668 buf[13] = buf2[13];
669 buf[14] = buf2[14];
670 buf[15] = buf2[15];
671
672 ret.Set(buf);
673 return ret;
674}
675
676void
677Ipv6Address::Print(std::ostream& os) const
678{
679 NS_LOG_FUNCTION(this << &os);
680
681 // note: part of this function has been adapted from inet_ntop6 Linux function.
682 // See http://www.net-snmp.org/dev/agent/inet__ntop_8c_source.html
683 // Author: Paul Vixie, 1996.
684
686 {
687 os << "::ffff:" << (unsigned int)m_address[12] << "." << (unsigned int)m_address[13] << "."
688 << (unsigned int)m_address[14] << "." << (unsigned int)m_address[15];
689 return;
690 }
691
692 uint16_t address[8];
693 uint8_t i;
694
695 for (i = 0; i < 8; i++)
696 {
697 address[i] = (uint16_t(m_address[2 * i]) << 8) | uint16_t(m_address[2 * i + 1]);
698 }
699
700 int8_t bestBase = -1;
701 int8_t bestLen = 0;
702 int8_t curBase = -1;
703 int8_t curLen = 0;
704
705 for (i = 0; i < 8; i++)
706 {
707 if (address[i] == 0)
708 {
709 if (curBase == -1)
710 {
711 curBase = i;
712 curLen = 1;
713 }
714 else
715 {
716 curLen++;
717 }
718 }
719 else
720 {
721 if (curBase != -1)
722 {
723 if (bestBase == -1 || curLen > bestLen)
724 {
725 bestBase = curBase;
726 bestLen = curLen;
727 }
728 curBase = -1;
729 }
730 }
731 }
732 if (curBase != -1)
733 {
734 if (bestBase == -1 || curLen > bestLen)
735 {
736 bestBase = curBase;
737 bestLen = curLen;
738 }
739 }
740 if (bestBase != -1 && bestLen < 2)
741 {
742 bestBase = -1;
743 }
744
745 for (i = 0; i < 8;)
746 {
747 // Are we inside the best run of 0x00's?
748 if (i == bestBase)
749 {
750 os << ':';
751 i += bestLen;
752 continue;
753 }
754 // Are we following an initial run of 0x00s or any real hex?
755 if (i != 0)
756 {
757 os << ':';
758 }
759 os << std::hex << (unsigned int)address[i];
760 i++;
761 }
762 // Was it a trailing run of 0x00's?
763 if (bestBase != -1 && (bestBase + bestLen) == 8)
764 {
765 os << ':';
766 }
767 os << std::dec;
768}
769
770bool
772{
773 NS_LOG_FUNCTION(this);
774 static Ipv6Address localhost("::1");
775 return (*this == localhost);
776}
777
778bool
780{
781 NS_LOG_FUNCTION(this);
782 if (m_address[0] == 0xff)
783 {
784 return true;
785 }
786 return false;
787}
788
789bool
791{
792 NS_LOG_FUNCTION(this);
793 if (m_address[0] == 0xff && m_address[1] == 0x02)
794 {
795 return true;
796 }
797 return false;
798}
799
800bool
802{
803 NS_LOG_FUNCTION(this);
804 static uint8_t v4MappedPrefix[12] =
805 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff};
806 if (memcmp(m_address, v4MappedPrefix, sizeof(v4MappedPrefix)) == 0)
807 {
808 return (true);
809 }
810 return (false);
811}
812
815{
816 NS_LOG_FUNCTION(this << prefix);
817 Ipv6Address ipv6;
818 uint8_t addr[16];
819 uint8_t pref[16];
820 unsigned int i = 0;
821
822 memcpy(addr, m_address, 16);
823 ((Ipv6Prefix)prefix).GetBytes(pref);
824
825 /* a little bit ugly... */
826 for (i = 0; i < 16; i++)
827 {
828 addr[i] = addr[i] & pref[i];
829 }
830 ipv6.Set(addr);
831 return ipv6;
832}
833
834bool
836{
837 NS_LOG_FUNCTION(this);
838
839 static Ipv6Address documentation("ff02::1:ff00:0");
840 if (CombinePrefix(Ipv6Prefix(104)) == documentation)
841 {
842 return true;
843 }
844 return false;
845}
846
847bool
849{
850 NS_LOG_FUNCTION(this);
851 static Ipv6Address allNodesI("ff01::1");
852 static Ipv6Address allNodesL("ff02::1");
853 static Ipv6Address allNodesR("ff03::1");
854 return (*this == allNodesI || *this == allNodesL || *this == allNodesR);
855}
856
857bool
859{
860 NS_LOG_FUNCTION(this);
861 static Ipv6Address allroutersI("ff01::2");
862 static Ipv6Address allroutersL("ff02::2");
863 static Ipv6Address allroutersR("ff03::2");
864 static Ipv6Address allroutersS("ff05::2");
865 return (*this == allroutersI || *this == allroutersL || *this == allroutersR ||
866 *this == allroutersS);
867}
868
869bool
871{
872 NS_LOG_FUNCTION(this);
873 static Ipv6Address any("::");
874 return (*this == any);
875}
876
877bool
879{
880 NS_LOG_FUNCTION(this);
881 static Ipv6Address documentation("2001:db8::0");
882 if (CombinePrefix(Ipv6Prefix(32)) == documentation)
883 {
884 return true;
885 }
886 return false;
887}
888
889bool
891{
892 NS_LOG_FUNCTION(this << prefix);
893
894 Ipv6Address masked = CombinePrefix(prefix);
896
897 return (masked == reference);
898}
899
900bool
902{
904 return address.CheckCompatible(GetType(), 16);
905}
906
907Ipv6Address::operator Address() const
908{
909 return ConvertTo();
910}
911
914{
915 NS_LOG_FUNCTION(this);
916 uint8_t buf[16];
917 Serialize(buf);
918 return Address(GetType(), buf, 16);
919}
920
923{
925 NS_ASSERT(address.CheckCompatible(GetType(), 16));
926 uint8_t buf[16];
927 address.CopyTo(buf);
928 return Deserialize(buf);
929}
930
931uint8_t
933{
935 static uint8_t type = Address::Register();
936 return type;
937}
938
941{
943 static Ipv6Address nmc("ff02::1");
944 return nmc;
945}
946
949{
951 static Ipv6Address rmc("ff02::2");
952 return rmc;
953}
954
957{
959 static Ipv6Address hmc("ff02::3");
960 return hmc;
961}
962
965{
967 static Ipv6Address loopback("::1");
968 return loopback;
969}
970
973{
975 static Ipv6Address zero("::");
976 return zero;
977}
978
981{
983 static Ipv6Address any("::");
984 return any;
985}
986
989{
991 static Ipv6Address ones("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff");
992 return ones;
993}
994
995void
996Ipv6Address::GetBytes(uint8_t buf[16]) const
997{
998 NS_LOG_FUNCTION(this << &buf);
999 memcpy(buf, m_address, 16);
1000}
1001
1002bool
1004{
1005 NS_LOG_FUNCTION(this);
1006 static Ipv6Address linkLocal("fe80::0");
1007 if (CombinePrefix(Ipv6Prefix(64)) == linkLocal)
1008 {
1009 return true;
1010 }
1011 return false;
1012}
1013
1014bool
1016{
1017 NS_LOG_FUNCTION(this);
1018 return (m_initialized);
1019}
1020
1021std::ostream&
1022operator<<(std::ostream& os, const Ipv6Address& address)
1023{
1024 address.Print(os);
1025 return os;
1026}
1027
1028std::istream&
1029operator>>(std::istream& is, Ipv6Address& address)
1030{
1031 std::string str;
1032 is >> str;
1033 address = Ipv6Address(str.c_str());
1034 return is;
1035}
1036
1038{
1039 NS_LOG_FUNCTION(this);
1040 memset(m_prefix, 0x00, 16);
1041 m_prefixLength = 64;
1042}
1043
1044Ipv6Prefix::Ipv6Prefix(const char* prefix)
1045{
1046 NS_LOG_FUNCTION(this << prefix);
1047 AsciiToIpv6Host(prefix, m_prefix);
1049}
1050
1051Ipv6Prefix::Ipv6Prefix(uint8_t prefix[16])
1052{
1053 NS_LOG_FUNCTION(this << &prefix);
1054 memcpy(m_prefix, prefix, 16);
1056}
1057
1058Ipv6Prefix::Ipv6Prefix(const char* prefix, uint8_t prefixLength)
1059{
1060 NS_LOG_FUNCTION(this << prefix);
1061 AsciiToIpv6Host(prefix, m_prefix);
1062
1063 uint8_t autoLength = GetMinimumPrefixLength();
1064 NS_ASSERT_MSG(autoLength <= prefixLength,
1065 "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address(prefix)
1066 << "/" << +prefixLength);
1067
1068 m_prefixLength = prefixLength;
1069}
1070
1071Ipv6Prefix::Ipv6Prefix(uint8_t prefix[16], uint8_t prefixLength)
1072{
1073 NS_LOG_FUNCTION(this << &prefix);
1074 memcpy(m_prefix, prefix, 16);
1075
1076 uint8_t autoLength = GetMinimumPrefixLength();
1077 NS_ASSERT_MSG(autoLength <= prefixLength,
1078 "Ipv6Prefix: address and prefix are not compatible: " << Ipv6Address(prefix)
1079 << "/" << +prefixLength);
1080
1081 m_prefixLength = prefixLength;
1082}
1083
1085{
1086 NS_LOG_FUNCTION(this << static_cast<uint32_t>(prefix));
1087 unsigned int nb = 0;
1088 unsigned int mod = 0;
1089 unsigned int i = 0;
1090
1091 memset(m_prefix, 0x00, 16);
1092 m_prefixLength = prefix;
1093
1094 NS_ASSERT(prefix <= 128);
1095
1096 nb = prefix / 8;
1097 mod = prefix % 8;
1098
1099 // protect memset with 'nb > 0' check to suppress
1100 // __warn_memset_zero_len compiler errors in some gcc>4.5.x
1101 if (nb > 0)
1102 {
1103 memset(m_prefix, 0xff, nb);
1104 }
1105 if (mod)
1106 {
1107 m_prefix[nb] = 0xff << (8 - mod);
1108 }
1109
1110 if (nb < 16)
1111 {
1112 nb++;
1113 for (i = nb; i < 16; i++)
1114 {
1115 m_prefix[i] = 0x00;
1116 }
1117 }
1118}
1119
1121{
1122 memcpy(m_prefix, prefix.m_prefix, 16);
1124}
1125
1127{
1128 memcpy(m_prefix, prefix->m_prefix, 16);
1130}
1131
1133{
1134 /* do nothing */
1135 NS_LOG_FUNCTION(this);
1136}
1137
1138bool
1140{
1141 NS_LOG_FUNCTION(this << a << b);
1142 uint8_t addrA[16];
1143 uint8_t addrB[16];
1144 unsigned int i = 0;
1145
1146 a.GetBytes(addrA);
1147 b.GetBytes(addrB);
1148
1149 /* a little bit ugly... */
1150 for (i = 0; i < 16; i++)
1151 {
1152 if ((addrA[i] & m_prefix[i]) != (addrB[i] & m_prefix[i]))
1153 {
1154 return false;
1155 }
1156 }
1157 return true;
1158}
1159
1160void
1161Ipv6Prefix::Print(std::ostream& os) const
1162{
1163 NS_LOG_FUNCTION(this << &os);
1164
1165 os << "/" << (unsigned int)GetPrefixLength();
1166}
1167
1170{
1172 static Ipv6Prefix prefix((uint8_t)128);
1173 return prefix;
1174}
1175
1178{
1180 static Ipv6Prefix ones((uint8_t)128);
1181 return ones;
1182}
1183
1186{
1188 static Ipv6Prefix prefix((uint8_t)0);
1189 return prefix;
1190}
1191
1192void
1193Ipv6Prefix::GetBytes(uint8_t buf[16]) const
1194{
1195 NS_LOG_FUNCTION(this << &buf);
1196 memcpy(buf, m_prefix, 16);
1197}
1198
1201{
1202 uint8_t prefixBytes[16];
1203 memcpy(prefixBytes, m_prefix, 16);
1204
1205 Ipv6Address convertedPrefix = Ipv6Address(prefixBytes);
1206 return convertedPrefix;
1207}
1208
1209uint8_t
1211{
1212 NS_LOG_FUNCTION(this);
1213 return m_prefixLength;
1214}
1215
1216void
1217Ipv6Prefix::SetPrefixLength(uint8_t prefixLength)
1218{
1219 NS_LOG_FUNCTION(this);
1220 m_prefixLength = prefixLength;
1221}
1222
1223uint8_t
1225{
1226 NS_LOG_FUNCTION(this);
1227
1228 uint8_t prefixLength = 0;
1229 bool stop = false;
1230
1231 for (int8_t i = 15; i >= 0 && !stop; i--)
1232 {
1233 uint8_t mask = m_prefix[i];
1234
1235 for (uint8_t j = 0; j < 8 && !stop; j++)
1236 {
1237 if ((mask & 1) == 0)
1238 {
1239 mask = mask >> 1;
1240 prefixLength++;
1241 }
1242 else
1243 {
1244 stop = true;
1245 }
1246 }
1247 }
1248
1249 return 128 - prefixLength;
1250}
1251
1252std::ostream&
1253operator<<(std::ostream& os, const Ipv6Prefix& prefix)
1254{
1255 prefix.Print(os);
1256 return os;
1257}
1258
1259std::istream&
1260operator>>(std::istream& is, Ipv6Prefix& prefix)
1261{
1262 std::string str;
1263 is >> str;
1264 prefix = Ipv6Prefix(str.c_str());
1265 return is;
1266}
1267
1268size_t
1270{
1271 uint8_t buf[16];
1272
1273 x.GetBytes(buf);
1274
1275 return lookuphash(buf, sizeof(buf), 0);
1276}
1277
1280
1281} /* namespace ns3 */
a polymophic address class
Definition: address.h:92
static uint8_t Register()
Allocate a new type id for a new type of address.
Definition: address.cc:146
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:43
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()(const Ipv6Address &x) const
Returns the hash of an IPv6 address.
Describes an IPv6 address.
Definition: ipv6-address.h:50
static uint8_t GetType()
Return the Type of address.
bool IsLinkLocal() const
If the IPv6 address is a link-local address (fe80::/64).
bool HasPrefix(const Ipv6Prefix &prefix) const
Compares an address and a prefix.
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.
static Ipv6Address MakeSolicitedAddress(Ipv6Address addr)
Make the solicited IPv6 address.
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
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 Set(const char *address)
Sets an Ipv6Address by parsing the input C-string.
void Serialize(uint8_t buf[16]) const
Serialize this address to a 16-byte buffer.
Ipv6Address()
Default constructor.
Address ConvertTo() const
convert the IPv6Address object to an Address object.
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.
bool IsInitialized() const
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.
static Ipv6Address MakeIpv4MappedAddress(Ipv4Address addr)
Make the Ipv4-mapped IPv6 address.
static Ipv6Address GetLoopback()
Get the loopback address.
Ipv6Address CombinePrefix(const Ipv6Prefix &prefix) const
Combine this address with a prefix.
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:595
static Ipv6Prefix GetLoopback()
Get the loopback prefix ( /128).
~Ipv6Prefix()
Destructor.
uint8_t m_prefix[16]
The prefix representation.
Definition: ipv6-address.h:590
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:44
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:46
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:46
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:44
static Mac8Address ConvertFrom(const Address &address)
Convert a generic address to a Mac8Address.
Definition: mac8-address.cc:61
static bool IsMatchingType(const Address &address)
Check that a generic Address is compatible with Mac8Address.
Definition: mac8-address.cc:70
void CopyTo(uint8_t *pBuffer) const
Writes address to buffer parameter.
Definition: mac8-address.cc:87
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:66
#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:86
#define NS_ABORT_MSG(msg)
Unconditional abnormal program termination with a message.
Definition: abort.h:49
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#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:40
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:129
ATTRIBUTE_HELPER_CPP(Length)
std::istream & operator>>(std::istream &is, Angles &a)
Definition: angles.cc:153
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.