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 #ifndef IPV6_ADDRESS_H
22 #define IPV6_ADDRESS_H
23 
24 #include <stdint.h>
25 #include <cstring>
26 
27 #include <ostream>
28 
29 #include "ns3/attribute-helper.h"
30 #include "ns3/address.h"
31 #include "ns3/ipv4-address.h"
32 #include "ns3/deprecated.h"
33 #include "mac8-address.h"
34 
35 namespace ns3 {
36 
37 class Ipv6Prefix;
38 class Mac16Address;
39 class Mac48Address;
40 class Mac64Address;
41 
42 /**
43  * \ingroup address
44  * \class Ipv6Address
45  * \brief Describes an IPv6 address.
46  * \see Ipv6Prefix
47  * \see attribute_Ipv6Address
48  */
49 class Ipv6Address
50 {
51 public:
52   /**
53    * \brief Default constructor.
54    */
55   Ipv6Address ();
56 
57   /**
58    * \brief Constructs an Ipv6Address by parsing the input C-string.
59    * \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
60    */
61   Ipv6Address (char const* address);
62 
63   /**
64    * \brief Constructs an Ipv6Address by using the input 16 bytes.
65    * \param address the 128-bit address
66    * \warning the parameter must point on a 16 bytes integer array!
67    */
68   Ipv6Address (uint8_t address[16]);
69 
70   /**
71    * \brief Copy constructor.
72    * \param addr Ipv6Address object
73    */
74   Ipv6Address (Ipv6Address const & addr);
75 
76   /**
77    * \brief Copy constructor.
78    * \param addr Ipv6Address pointer
79    */
80   Ipv6Address (Ipv6Address const* addr);
81 
82   /**
83    * \brief Destructor.
84    */
85   ~Ipv6Address ();
86 
87   /**
88    * \brief Sets an Ipv6Address by parsing the input C-string.
89    * \param address the C-string containing the IPv6 address (e.g. 2001:660:4701::1).
90    */
91   void Set (char const* address);
92 
93   /**
94    * \brief Set an Ipv6Address by using the input 16 bytes.
95    *
96    * \param address the 128-bit address
97    * \warning the parameter must point on a 16 bytes integer array!
98    */
99   void Set (uint8_t address[16]);
100 
101   /**
102    * \brief Serialize this address to a 16-byte buffer.
103    * \param buf the output buffer to which this address gets overwritten with this
104    * Ipv6Address
105    */
106   void Serialize (uint8_t buf[16]) const;
107 
108   /**
109    * \brief Deserialize this address.
110    * \param buf buffer to read address from
111    * \return an Ipv6Address
112    */
113   static Ipv6Address Deserialize (const uint8_t buf[16]);
114 
115   /**
116    * \brief Make the solicited IPv6 address.
117    * \param addr the IPv6 address
118    * \return Solicited IPv6 address
119    */
120   static Ipv6Address MakeSolicitedAddress (Ipv6Address addr);
121 
122   /**
123    * \brief Make the Ipv4-mapped IPv6 address.
124    * \param addr the IPv4 address
125    * \return Ipv4-mapped IPv6 address
126    */
127   static Ipv6Address MakeIpv4MappedAddress (Ipv4Address addr);
128 
129   /**
130    * \brief Return the Ipv4 address.
131    * \return Ipv4 address
132    */
133   Ipv4Address GetIpv4MappedAddress () const;
134 
135   /**
136    * \brief Make the autoconfigured IPv6 address from a Mac address.
137    *
138    * Actually the MAC supported are: Mac8, Mac16, Mac48, and Mac64.
139    *
140    * \param addr the MAC address.
141    * \param prefix the IPv6 prefix
142    * \return autoconfigured IPv6 address
143    */
144   static Ipv6Address MakeAutoconfiguredAddress (Address addr, Ipv6Address prefix);
145 
146   /**
147    * \brief Make the autoconfigured IPv6 address from a Mac address.
148    *
149    * Actually the MAC supported are: Mac8, Mac16, Mac48, and Mac64.
150    *
151    * \param addr the MAC address.
152    * \param prefix the IPv6 prefix
153    * \return autoconfigured IPv6 address
154    */
155 
156   static Ipv6Address MakeAutoconfiguredAddress (Address addr, Ipv6Prefix prefix);
157 
158   /**
159    * \brief Make the autoconfigured IPv6 address with Mac16Address.
160    *
161    * The EUI-64 scheme used is based on the \RFC{4944}.
162    *
163    * \param addr the MAC address (16 bits).
164    * \param prefix the IPv6 prefix
165    * \return autoconfigured IPv6 address
166    */
167   static Ipv6Address MakeAutoconfiguredAddress (Mac16Address addr, Ipv6Address prefix);
168 
169   /**
170    * \brief Make the autoconfigured IPv6 address with Mac48Address.
171    *
172    * The EUI-64 scheme used is based on \RFC{2464}.
173    *
174    * \param addr the MAC address (48 bits).
175    * \param prefix the IPv6 prefix
176    * \return autoconfigured IPv6 address
177    */
178   static Ipv6Address MakeAutoconfiguredAddress (Mac48Address addr, Ipv6Address prefix);
179 
180   /**
181    * \brief Make the autoconfigured IPv6 address with Mac64Address.
182    * \param addr the MAC address (64 bits).
183    * \param prefix the IPv6 prefix
184    * \return autoconfigured IPv6 address
185    */
186   static Ipv6Address MakeAutoconfiguredAddress (Mac64Address addr, Ipv6Address prefix);
187 
188   /**
189    * \brief Make the autoconfigured IPv6 address with Mac8Address.
190    *
191    * The EUI-64 scheme used is loosely based on the \RFC{2464}.
192    *
193    * \param addr the Mac8Address address (8 bits).
194    * \param prefix the IPv6 prefix
195    * \return autoconfigured IPv6 address
196    */
197   static Ipv6Address MakeAutoconfiguredAddress (Mac8Address addr, Ipv6Address prefix);
198 
199   /**
200    * \brief Make the autoconfigured link-local IPv6 address from a Mac address.
201    *
202    * Actually the MAC supported are: Mac8, Mac16, Mac48, and Mac64.
203    *
204    * \param mac the MAC address.
205    * \return autoconfigured link-local IPv6 address
206    */
207   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Address mac);
208 
209   /**
210    * \brief Make the autoconfigured link-local IPv6 address with Mac16Address.
211    *
212    * The EUI-64 scheme used is based on the \RFC{4944}.
213    *
214    * \param mac the MAC address (16 bits).
215    * \return autoconfigured link-local IPv6 address
216    */
217   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac16Address mac);
218 
219   /**
220    * \brief Make the autoconfigured link-local IPv6 address with Mac48Address.
221    *
222    * The EUI-64 scheme used is based on \RFC{2464}.
223    *
224    * \param mac the MAC address (48 bits).
225    * \return autoconfigured link-local IPv6 address
226    */
227   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac48Address mac);
228 
229   /**
230    * \brief Make the autoconfigured link-local IPv6 address with Mac64Address.
231    * \param mac the MAC address (64 bits).
232    * \return autoconfigured link-local IPv6 address
233    */
234   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac64Address mac);
235 
236   /**
237    * \brief Make the autoconfigured link-local IPv6 address with Mac8Address.
238    *
239    * The EUI-64 scheme used is loosely based on the \RFC{2464}.
240    *
241    * \param mac the MAC address (8 bits).
242    * \return autoconfigured link-local IPv6 address
243    */
244   static Ipv6Address MakeAutoconfiguredLinkLocalAddress (Mac8Address mac);
245 
246   /**
247    * \brief Print this address to the given output stream.
248    *
249    * The print format is in the typical "2001:660:4701::1".
250    * \param os the output stream to which this Ipv6Address is printed
251    */
252   void Print (std::ostream& os) const;
253 
254   /**
255    * \brief If the IPv6 address is localhost (::1).
256    * \return true if localhost, false otherwise
257    */
258   bool IsLocalhost () const;
259 
260   /**
261    * \brief If the IPv6 address is multicast (ff00::/8).
262    * \return true if multicast, false otherwise
263    */
264   bool IsMulticast () const;
265 
266   /**
267    * \brief If the IPv6 address is link-local multicast (ff02::/16).
268    * \return true if link-local multicast, false otherwise
269    */
270   bool IsLinkLocalMulticast () const;
271 
272   /**
273    * \brief If the IPv6 address is "all nodes multicast" (ff02::1/8).
274    * \return true if "all nodes multicast", false otherwise
275    */
276   bool IsAllNodesMulticast () const;
277 
278   /**
279    * \brief If the IPv6 address is "all routers multicast" (ff02::2/8).
280    * \return true if "all routers multicast", false otherwise
281    */
282   bool IsAllRoutersMulticast () const;
283 
284   /**
285    * \brief If the IPv6 address is a link-local address (fe80::/64).
286    * \return true if the address is link-local, false otherwise
287    */
288   bool IsLinkLocal () const;
289 
290   /**
291    * \brief If the IPv6 address is a Solicited multicast address.
292    * \return true if it is, false otherwise
293    */
294   bool IsSolicitedMulticast () const;
295 
296   /**
297    * \brief If the IPv6 address is the "Any" address.
298    * \return true if it is, false otherwise
299    */
300   bool IsAny () const;
301 
302   /**
303    * \brief If the IPv6 address is a documentation address (2001:DB8::/32).
304    * \return true if the address is documentation, false otherwise
305    */
306   bool IsDocumentation () const;
307 
308   /**
309    * \brief Compares an address and a prefix.
310    * \param prefix the prefix to compare with
311    * \return true if the address has the given prefix
312    */
313   bool HasPrefix (Ipv6Prefix const& prefix) const;
314 
315   /**
316    * \brief Combine this address with a prefix.
317    * \param prefix a IPv6 prefix
318    * \return an IPv6 address that is this address combined
319    * (bitwise AND) with a prefix, yielding an IPv6 network address.
320    */
321   Ipv6Address CombinePrefix (Ipv6Prefix const & prefix) const;
322 
323   /**
324    * \brief If the Address matches the type.
325    * \param address other address
326    * \return true if the type matches, false otherwise
327    */
328   static bool IsMatchingType (const Address& address);
329 
330   /**
331    * \brief If the address is an IPv4-mapped address
332    * \return true if address is an IPv4-mapped address, otherwise false.
333    */
334   bool IsIpv4MappedAddress() const;
335 
336   /**
337    * \brief Convert to Address object
338    */
339   operator Address () const;
340 
341   /**
342    * \brief Convert the Address object into an Ipv6Address ones.
343    * \param address address to convert
344    * \return an Ipv6Address
345    */
346   static Ipv6Address ConvertFrom (const Address& address);
347 
348   /**
349    * \return true if address is initialized (i.e., set to something), false otherwise
350    */
351   bool IsInitialized (void) const;
352 
353   /**
354    * \brief Get the 0 (::) Ipv6Address.
355    * \return the :: Ipv6Address representation
356    */
357   static Ipv6Address GetZero ();
358 
359   /**
360    * \brief Get the "any" (::) Ipv6Address.
361    * \return the "any" (::) Ipv6Address
362    */
363   static Ipv6Address GetAny ();
364 
365   /**
366    * \brief Get the "all nodes multicast" address.
367    * \return the "ff02::2/8" Ipv6Address representation
368    */
369   static Ipv6Address GetAllNodesMulticast ();
370 
371   /**
372    * \brief Get the "all routers multicast" address.
373    * \return the "ff02::2/8" Ipv6Address representation
374    */
375   static Ipv6Address GetAllRoutersMulticast ();
376 
377   /**
378    * \brief Get the "all hosts multicast" address.
379    * \return the "ff02::3/8" Ipv6Address representation
380    */
381   static Ipv6Address GetAllHostsMulticast ();
382 
383   /**
384    * \brief Get the loopback address.
385    * \return the "::1/128" Ipv6Address representation.
386    */
387   static Ipv6Address GetLoopback ();
388 
389   /**
390    * \brief Get the "all-1" IPv6 address (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
391    * \return all-1 Ipv6Address representation
392    */
393   static Ipv6Address GetOnes ();
394 
395   /**
396    * \brief Get the bytes corresponding to the address.
397    * \param buf buffer to store the data
398    */
399   void GetBytes (uint8_t buf[16]) const;
400 
401 private:
402   /**
403    * \brief convert the IPv6Address object to an Address object.
404    * \return the Address object corresponding to this object.
405    */
406   Address ConvertTo (void) const;
407 
408   /**
409    * \brief Return the Type of address.
410    * \return type of address
411    */
412   static uint8_t GetType (void);
413 
414   /**
415    * \brief The address representation on 128 bits (16 bytes).
416    */
417   uint8_t m_address[16];
418   bool m_initialized; //!< IPv6 address has been explicitly initialized to a valid value.
419 
420   /**
421    * \brief Equal to operator.
422    *
423    * \param a the first operand.
424    * \param b the first operand.
425    * \returns true if the operands are equal.
426    */
427   friend bool operator == (Ipv6Address const &a, Ipv6Address const &b);
428 
429   /**
430    * \brief Not equal to operator.
431    *
432    * \param a the first operand.
433    * \param b the first operand.
434    * \returns true if the operands are not equal.
435    */
436   friend bool operator != (Ipv6Address const &a, Ipv6Address const &b);
437 
438   /**
439    * \brief Less than to operator.
440    *
441    * \param a the first operand.
442    * \param b the first operand.
443    * \returns true if the first operand is less than the second.
444    */
445   friend bool operator < (Ipv6Address const &a, Ipv6Address const &b);
446 };
447 
448 /**
449  * \ingroup address
450  * \class Ipv6Prefix
451  * \brief Describes an IPv6 prefix. It is just a bitmask like Ipv4Mask.
452  * \see Ipv6Address
453  * \see attribute_Ipv6Prefix
454  */
455 class Ipv6Prefix
456 {
457 public:
458   /**
459    * \brief Default constructor.
460    */
461   Ipv6Prefix ();
462 
463   /**
464    * \brief Constructs an Ipv6Prefix by using the input 16 bytes.
465    *
466    * The prefix length is calculated as the minimum prefix length, i.e.,
467    * 2001:db8:cafe:: will have a 47 bit prefix length.
468    *
469    * \param prefix the 128-bit prefix
470    */
471   Ipv6Prefix (uint8_t prefix[16]);
472 
473   /**
474    * \brief Constructs an Ipv6Prefix by using the input string.
475    *
476    * The prefix length is calculated as the minimum prefix length, i.e.,
477    * 2001:db8:cafe:: will have a 47 bit prefix length.
478    *
479    * \param prefix the 128-bit prefix
480    */
481   Ipv6Prefix (char const* prefix);
482 
483   /**
484    * \brief Constructs an Ipv6Prefix by using the input 16 bytes.
485    * \param prefix the 128-bit prefix
486    * \param prefixLength the prefix length
487    */
488   Ipv6Prefix (uint8_t prefix[16], uint8_t prefixLength);
489 
490   /**
491    * \brief Constructs an Ipv6Prefix by using the input string.
492    * \param prefix the 128-bit prefix
493    * \param prefixLength the prefix length
494    */
495   Ipv6Prefix (char const* prefix, uint8_t prefixLength);
496 
497   /**
498    * \brief Constructs an Ipv6Prefix by using the input number of bits.
499    * \param prefix number of bits of the prefix (0 - 128)
500    * \note A valid number of bits is between 0 and 128).
501    */
502   Ipv6Prefix (uint8_t prefix);
503 
504   /**
505    * \brief Copy constructor.
506    * \param prefix Ipv6Prefix object
507    */
508   Ipv6Prefix (Ipv6Prefix const& prefix);
509 
510   /**
511    * \brief Copy constructor.
512    * \param prefix Ipv6Prefix pointer
513    */
514   Ipv6Prefix (Ipv6Prefix const* prefix);
515 
516   /**
517    * \brief Destructor.
518    */
519   ~Ipv6Prefix ();
520 
521   /**
522    * \brief If the Address match the type.
523    * \param a a first address
524    * \param b a second address
525    * \return true if the type match, false otherwise
526    */
527   bool IsMatch (Ipv6Address a, Ipv6Address b) const;
528 
529   /**
530    * \brief Get the bytes corresponding to the prefix.
531    * \param buf buffer to store the data
532    */
533   void GetBytes (uint8_t buf[16]) const;
534 
535   /**
536    * \brief Convert the Prefix into an IPv6 Address.
537    * \return an IPv6 address representing the prefix
538    */
539   Ipv6Address ConvertToIpv6Address () const;
540 
541   /**
542    * \brief Get prefix length.
543    * \return prefix length
544    */
545   uint8_t GetPrefixLength () const;
546 
547   /**
548    * \brief Set prefix length.
549    * \param prefixLength the prefix length
550    */
551   void SetPrefixLength (uint8_t prefixLength);
552 
553    /**
554     * \brief Get the minimum prefix length, i.e., 128 - the length of the largest sequence trailing zeroes.
555     * \return minimum prefix length
556     */
557   uint8_t GetMinimumPrefixLength () const;
558 
559   /**
560    * \brief Print this address to the given output stream.
561    *
562    * The print format is in the typical "2001:660:4701::1".
563    * \param os the output stream to which this Ipv6Address is printed
564    */
565   void Print (std::ostream &os) const;
566 
567   /**
568    * \brief Get the loopback prefix ( /128).
569    * \return a Ipv6Prefix corresponding to loopback prefix
570    */
571   static Ipv6Prefix GetLoopback ();
572 
573   /**
574    * \brief Get the "all-1" IPv6 mask (ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff).
575    * \return /128 Ipv6Prefix representation
576    */
577   static Ipv6Prefix GetOnes ();
578 
579   /**
580    * \brief Get the zero prefix ( /0).
581    * \return an Ipv6Prefix
582    */
583   static Ipv6Prefix GetZero ();
584 
585 private:
586   /**
587    * \brief The prefix representation.
588    */
589   uint8_t m_prefix[16];
590 
591   /**
592    * \brief The prefix length.
593    */
594   uint8_t m_prefixLength;
595 
596   /**
597    * \brief Equal to operator.
598    *
599    * \param a the first operand
600    * \param b the first operand
601    * \returns true if the operands are equal
602    */
603   friend bool operator == (Ipv6Prefix const &a, Ipv6Prefix const &b);
604 
605   /**
606    * \brief Not equal to operator.
607    *
608    * \param a the first operand
609    * \param b the first operand
610    * \returns true if the operands are not equal
611    */
612   friend bool operator != (Ipv6Prefix const &a, Ipv6Prefix const &b);
613 };
614 
615 ATTRIBUTE_HELPER_HEADER (Ipv6Address);
616 ATTRIBUTE_HELPER_HEADER (Ipv6Prefix);
617 
618 /**
619  * \brief Stream insertion operator.
620  *
621  * \param os the reference to the output stream
622  * \param address the Ipv6Address
623  * \returns the reference to the output stream
624  */
625 std::ostream & operator << (std::ostream& os, Ipv6Address const& address);
626 
627 /**
628  * \brief Stream insertion operator.
629  *
630  * \param os the reference to the output stream
631  * \param prefix the Ipv6Prefix
632  * \returns the reference to the output stream
633  */
634 std::ostream & operator << (std::ostream& os, Ipv6Prefix const& prefix);
635 
636 /**
637  * \brief Stream extraction operator.
638  *
639  * \param is the reference to the input stream
640  * \param address the Ipv6Address
641  * \returns the reference to the input stream
642  */
643 std::istream & operator >> (std::istream &is, Ipv6Address &address);
644 
645 /**
646  * \brief Stream extraction operator.
647  *
648  * \param is the reference to the input stream
649  * \param prefix the Ipv6Preofix
650  * \returns the reference to the input stream
651  */
652 std::istream & operator >> (std::istream &is, Ipv6Prefix &prefix);
653 
654 inline bool operator == (const Ipv6Address& a, const Ipv6Address& b)
655 {
656   return (!std::memcmp (a.m_address, b.m_address, 16));
657 }
658 
659 inline bool operator != (const Ipv6Address& a, const Ipv6Address& b)
660 {
661   return std::memcmp (a.m_address, b.m_address, 16);
662 }
663 
664 inline bool operator < (const Ipv6Address& a, const Ipv6Address& b)
665 {
666   return (std::memcmp (a.m_address, b.m_address, 16) < 0);
667 }
668 
669 inline bool operator == (const Ipv6Prefix& a, const Ipv6Prefix& b)
670 {
671   return (!std::memcmp (a.m_prefix, b.m_prefix, 16));
672 }
673 
674 inline bool operator != (const Ipv6Prefix& a, const Ipv6Prefix& b)
675 {
676   return std::memcmp (a.m_prefix, b.m_prefix, 16);
677 }
678 
679 /**
680  * \class Ipv6AddressHash
681  * \brief Hash function class for IPv6 addresses.
682  */
683 class Ipv6AddressHash
684 {
685 public:
686   /**
687    * \brief Returns the hash of an IPv6 address.
688    * \param x IPv6 address to hash
689    * \returns the hash of the address
690    */
691   size_t operator () (Ipv6Address const &x) const;
692 };
693 
694 } /* namespace ns3 */
695 
696 #endif /* IPV6_ADDRESS_H */
697 
698