Doc. no: N3603 Date: 2013-03-17 Reply-To: Christopher Kohlhoff <chris@kohlhoff.com>
Table of Contents
This proposal describes a three-class design for IP address classes:
ip::address
, for use in IP version independent
code.
ip::address_v4
.
ip::address_v6
.
This proposal describes only types necessary to support the manipulation of IP (Internet Protocol) addresses. Other networking facilities, such as sockets and name resolution, are outside the scope of this proposal.
The proposed interface is primarily intended for use by developers writing programs with a networking component, and in particular programs that utilise internet protocols such as TCP and UDP.
This proposal is based on the IP address classes in the Boost.Asio library. The proposed text is from N2175 "Networking Library Proposal for TR2 (Revision 1)" with small modifications to reflect enhancements made to Boost.Asio since 2007. At present, the proposed text does not differ significantly from the corresponding classes in Boost.Asio.
This is a pure library proposal. It does not add any new language features, nor does it alter any existing standard library headers.
This library can be implemented using compilers that conform to the C++11 standard. An implementation of this library requires operating system-specific functions that lie outside the C++11 standard.
Ideally, most network applications should be written so that they are independent
of the IP version in use. For this reason, this proposal provides the ip::address
class as a vocabulary type.
The characteristics of the ip::address
class are as follows:
AF_INET
or AF_INET6
sockets.
ip::address
object so that it corresponds to a default-constructed IPv4 address.
(This particular value was chosen in Boost.Asio
as IPv6 networking support is not universal, and the value is also the
smallest in terms of ip::address::operator<
.)
In general, the ip::address
interface is designed to provide
just enough support to use IP addresses in version-independent networking
contexts. When a program requires a facility that applies to only IPv4 or
IPv6 addresses, the developer is expected to use one of the version-specific
types described below.
The question of whether to use a type-erased vocabulary type was discussed during the 2005 Boost review of Boost.Asio. What was originally proposed was to distinguish IPv4 and IPv6 using separate types and to use template-based genericity to be version independent. This approach was rejected by the participants in the review.
The point is that most applications do indeed need to be version independent at runtime. For example:
Usage: my_tcp_server <bind_to_address> ./my_tcp_server 0.0.0.0 # Binds to IPv4 wildcard address ./my_tcp_server 127.0.0.1 # Binds to specific IPv4 address ./my_tcp_server ::0 # Binds to IPv6 wildcard address ./my_tcp_server ::1 # Binds to specific IPv6 address
The implementation of my_tcp_server
only deals in one
type of address class. No templates are required.
Forcing all applications to create their own runtime switching was deemed infeasible. Dual-stack support is not universal and cannot be relied on for portable applications. Hence the current form in Boost.Asio exists as a tradeoff between supporting the easy development of version-independent applications and the low level access for those who need it.
The version-specific address classes, ip::address_v4
and ip::address_v6
, are provided for use cases
where finer grained control is required, such as:
The characteristics of the ip::address_v4
class are as follows:
AF_INET
sockets.
a.b.c.d
). Rejects other string forms.
The characteristics of the ip::address_v6
class are as follows:
AF_INET6
sockets.
abcd:efgh:...
,
etc). Rejects other string forms.
ip::address_v4
,
with the creation function determining which conversion is used (to v4-mapped
or v4-compatible).
ip::address_v4
,
if the address is one of the above v4 forms.
An alternative IP address design has been proposed that revolves around two classes. Using the naming conventions of this proposal, these classes would be:
ip::address
,
for use in IP version independent code. Unlike the three-class design,
this class is also intended to represent IPv6 addresses.
ip::address_v4
.
This design appears to be driven by a desire to push people toward the version-independent type, but to still meet the space constraints of applications that must deal with large numbers of IPv4 addresses. The design is based on the notion that IPv4 addresses are a subset of IPv6 addresses, and that IPv4 addresses can be mapped, and stored, into IPv6.
The author rejects this design for a number of reasons.
Superficially, the two-class design gives a special place to IPv4 addresses ("I can see the IPv4 class... but where's IPv6?").
What is more important, however, is that the design prevents a programmer from utilising the C++ type system to create efficient function overloads based on the IP version. A programmer can provide a function overload specifically for IPv4 addresses:
void some_function(const ip::address_v4& a) { ... }
but when it comes to supporting IPv6 addresses the programmer has no choice but to resort to runtime dispatching:
void some_function(const ip::address& a) { if (a.is_v6()) { ... } else { ... } }
There is no way for an programmer to express an interface that wants to deal only in IPv6 addresses.
A pure IPv4 address is subtly different from one mapped into an IPv6 address. This ties into the question of the larger networking ecosystem, in particular how one might use the address classes in conjunction with sockets. For example:
"1.2.3.4" ->
AF_INET
socket
"::ffff:1.2.3.4" ->
AF_INET6
with dual stack socket
"fe80::...:12:34" ->
AF_INET6
with or without dual stack
Things like dual stack support are far from universal and some IPv6 transition/portability guides recommend explicitly disabling dual stack support. The author does not think that standardized address classes should push people in one or other direction with respect to dual stack usage. Thus, it is important to preserve the original type of the IP address.
As there is no separate type for IPv6, the vocabulary type ip::address
must support all IPv6-related operations. Some of these operations may lack
a meaningful implementation for IPv4 addresses, and so behave in quite different
ways (e.g. fail). Note that some of these operations are outside the scope
of standardization, i.e. they may be part of an application.
This proposal follows Boost.Asio
in the use of the namespace ip::
, rather than the prefix ip_
,
for the address classes. This namespace is part of a wider taxonomy and encompasses
other IP-related facilities, including:
tcp
,
udp
and icmp
).
The author notes that the abbreviation IP
is an overloaded term, even within computing. If backward compatibility was
not a concern, he would instead prefer the namespace inet::
. This is consistent with POSIX
naming, as in AF_INET
, inet_ntop()
,
etc. It is also unambiguously network related and so might be placed directly
under the std
namespace,
i.e. std::inet
.
This clause describes components that C++ programs may use to manipulate IP addresses.
namespace std { namespace net { // Internet protocol addresses: namespace ip { class address; // address comparisons: bool operator==(const address&, const address&); bool operator!=(const address&, const address&); bool operator< (const address&, const address&); bool operator> (const address&, const address&); bool operator<=(const address&, const address&); bool operator>=(const address&, const address&); // address I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>&, const address&); class address_v4; // address_v4 comparisons: bool operator==(const address_v4&, const address_v4&); bool operator!=(const address_v4&, const address_v4&); bool operator< (const address_v4&, const address_v4&); bool operator> (const address_v4&, const address_v4&); bool operator<=(const address_v4&, const address_v4&); bool operator>=(const address_v4&, const address_v4&); // address_v4 I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>&, const address_v4&); class address_v6; // address_v6 comparisons: bool operator==(const address_v6&, const address_v6&); bool operator!=(const address_v6&, const address_v6&); bool operator< (const address_v6&, const address_v6&); bool operator> (const address_v6&, const address_v6&); bool operator<=(const address_v6&, const address_v6&); bool operator>=(const address_v6&, const address_v6&); // address_v6 I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>&, const address_v6&); } // namespace ip } // namespace net // hash support template <class T> struct hash; template <> struct hash<net::ip::address>; template <> struct hash<net::ip::address_v4>; template <> struct hash<net::ip::address_v6>; } // namespace std
namespace std { namespace net { namespace ip { class address { public: // constructors: address(); address(const address_v4& addr); address(const address_v6& addr); // assignment: address& operator=(const address_v4& addr); address& operator=(const address_v6& addr); // members: bool is_unspecified() const; bool is_loopback() const; bool is_multicast() const; bool is_v4() const; bool is_v6() const; address_v4 to_v4() const; address_v6 to_v6() const; string to_string() const; string to_string(error_code& ec) const; // static members: static address from_string(const string& str); static address from_string(const string& str, error_code& ec); }; // address comparisons: bool operator==(const address& a, const address& b); bool operator!=(const address& a, const address& b); bool operator< (const address& a, const address& b); bool operator> (const address& a, const address& b); bool operator<=(const address& a, const address& b); bool operator>=(const address& a, const address& b); // address I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address& addr); } // namespace ip } // namespace net } // namespace std
address();
Effects: Constructs an object of class
address
.
Postconditions: The postconditions of this function are indicated in the table below.
Table 1. address::address() effects
expression |
value |
---|---|
|
|
|
|
|
|
address(const address_v4& addr);
Effects: Constructs an object of class
address
, initialising it with the specified IP version 4 address.
Postconditions: The postconditions of this function are indicated in the table below.
Table 2. address::address(const address_v4&) effects
expression |
value |
---|---|
|
|
|
|
|
|
address(const address_v6& addr);
Effects: Constructs an object of class
address
, initialising it with the specified IP version 6 address.
Postconditions: The postconditions of this function are indicated in the table below.
Table 3. address::address(const address_v6&) effects
expression |
value |
---|---|
|
|
|
|
|
|
address& operator=(const address_v4& addr);
Effects: Assigns the specified IP version 4 address into an object of class
address
.
Returns:
*this
.
Postconditions: The postconditions of this function are indicated in the table below.
Table 4. address& address::operator=(const address_v4&) effects
expression |
value |
---|---|
|
|
|
|
|
|
address& operator=(const address_v6& addr);
Effects: Assigns the specified IP version 6 address into an object of class
address
.
Returns:
*this
.
Postconditions: The postconditions of this function are indicated in the table below.
Table 5. address& address::operator=(const address_v6&) effects
expression |
value |
---|---|
|
|
|
|
|
|
bool is_unspecified() const;
Returns:
is_v4() ? to_v4().is_unspecified() : to_v6().is_unspecified()
.
bool is_loopback() const;
Returns:
is_v4() ? to_v4().is_loopback() : to_v6().is_loopback()
.
bool is_multicast() const;
Returns:
is_v4() ? to_v4().is_multicast() : to_v6().is_multicast()
.
bool is_v4() const;
Returns:
true
if the object contains an IP version 4 address.
bool is_v6() const;
Returns:
true
if the object contains an IP version 6 address.
address_v4 to_v4() const;
Returns: The IP version 4 address contained by the object.
Throws:
bad_cast
ifis_v4()
is false.
address_v6 to_v6() const;
Returns: The IP version 6 address contained by the object.
Throws:
bad_cast
ifis_v6()
is false.
string to_string() const; string to_string(error_code& ec) const;
Returns:
is_v4() ? to_v4().to_string(ec) : to_v6().to_string(ec)
.
static address from_string(const string& str); static address from_string(const string& str, error_code& ec);
Effects: Converts a string representation of an address into an object of class
address
, as if by calling:address a; address_v6 v6a = address_v6::from_string(str, ec); if (!ec) a = v6a; else { address_v4 v4a = address_v4::from_string(str, ec); if (!ec) a = v4a; }
Returns:
a
.
bool operator==(const address& a, const address& b);
Returns:
(a.is_v4() && b.is_v4() && a.to_v4() == b.to_v4()) || (a.is_v6() && b.is_v6() && a.to_v6() == b.to_v6())
.
bool operator!=(const address& a, const address& b);
Returns:
!(a == b)
.
bool operator< (const address& a, const address& b);
Returns:
(a.is_v4() && b.is_v4() && a.to_v4() < b.to_v4()) || (a.is_v6() && b.is_v6() && a.to_v6() < b.to_v6()) || (a.is_v4() && b.is_v6())
.
bool operator> (const address& a, const address& b);
Returns:
b < a
.
bool operator<=(const address& a, const address& b);
Returns:
!(b < a)
.
bool operator>=(const address& a, const address& b);
Returns:
!(a < b)
.
template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address& addr);
Effects: Outputs the string representation of the address to the stream, as if it were implemented as follows:
error_code ec; string s = addr.to_string(ec); if (ec) { if (os.exceptions() & ios_base::failbit) throw system_error(ec); else os.setstate(ios_base::failbit); } else for (string::iterator i = s.begin(); i != s.end(); ++i) os << os.widen(*i);
Returns:
os
.
namespace std { namespace net { namespace ip { class address_v4 { public: // types: typedef array<unsigned char, 4> bytes_type; // constructors: address_v4(); explicit address_v4(const bytes_type& bytes); explicit address_v4(unsigned long val); // members: bool is_unspecified() const; bool is_loopback() const; bool is_class_a() const; bool is_class_b() const; bool is_class_c() const; bool is_multicast() const; bytes_type to_bytes() const; unsigned long to_ulong() const; string to_string() const; string to_string(error_code& ec) const; // static members: static address_v4 from_string(const string& str); static address_v4 from_string(const string& str, error_code& ec); static address_v4 any(); static address_v4 loopback(); static address_v4 broadcast(); static address_v4 broadcast(const address_v4& addr, const address_v4& mask); static address_v4 netmask(const address_v4& addr); }; // address_v4 comparisons: bool operator==(const address_v4& a, const address_v4& b); bool operator!=(const address_v4& a, const address_v4& b); bool operator< (const address_v4& a, const address_v4& b); bool operator> (const address_v4& a, const address_v4& b); bool operator<=(const address_v4& a, const address_v4& b); bool operator>=(const address_v4& a, const address_v4& b); // address_v4 I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address_v4& addr); } // namespace ip } // namespace net } // namespace std
address_v4();
Effects: Constructs an object of class
address_v4
.
Postconditions: The postconditions of this function are indicated in the table below.
address_v4(const bytes_type& bytes);
Effects: Constructs an object of class
address_v4
.
Requires: Each element of the array
bytes
is in the range[0, 0xFF]
.
Throws:
out_of_range
if any element of the arraybytes
is not in the range[0, 0xFF]
. [Note: For implementations whereUCHAR_MAX == 0xFF
, no out-of-range detection is needed. —end note]
Postconditions: The postconditions of this function are indicated in the table below.
Table 7. address_v4::address_v4(const bytes_type&) effects
expression |
value |
---|---|
|
{ bytes[0], bytes[1], bytes[2], bytes[3] }
|
|
(bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]
|
address_v4(unsigned long val);
Effects: Constructs an object of class
address_v4
.
Requires:
val
is in the range[0, 0xFFFFFFFF]
.
Throws:
out_of_range
ifval
is not in the range[0, 0xFFFFFFFF]
. [Note: For implementations whereULONG_MAX == 0xFFFFFFFF
, no out-of-range detection is needed. —end note]
Postconditions: The postconditions of this function are indicated in the table below.
Table 8. address_v4::address_v4(unsigned long) effects
expression |
value |
---|---|
|
{ (val >> 24) & 0xFF, (val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF }
|
|
|
bool is_unspecified() const;
Returns:
to_ulong() == 0
.
bool is_loopback() const;
Returns:
(to_ulong() & 0xFF000000) == 0x7F
.
bool is_class_a() const;
Returns:
(to_ulong() & 0x80000000) == 0
.
bool is_class_b() const;
Returns:
(to_ulong() & 0xC0000000) == 0x80000000
.
bool is_class_c() const;
Returns:
(to_ulong() & 0xE0000000) == 0xC0000000
.
bool is_multicast() const;
Returns:
(to_ulong() & 0xF0000000) == 0xE0000000
.
bytes_type to_bytes() const;
Returns: A representation of the address in network byte order.
unsigned long to_ulong() const;
Returns: A representation of the address in host byte order.
string to_string() const; string to_string(error_code& ec) const;
Effects: Converts an address into a string representation, as if by POSIX
inet_ntop()
when invoked with address familyAF_INET
.
Returns: If successful, the string representation of the address. Otherwise
string()
.
static address_v4 from_string(const string& str); static address_v4 from_string(const string& str, error_code& ec);
Effects: Converts a string representation of an address into a corresponding
address_v4
value, as if by POSIXinet_pton()
when invoked with address familyAF_INET
.
Returns: If successful, an
address_v4
value corresponding to the stringstr
. Otherwiseaddress_v4()
.
static address_v4 any();
Returns:
address_v4()
.
static address_v4 loopback();
Returns:
address_v4(0x7F000001)
.
static address_v4 broadcast();
Returns:
address_v4(0xFFFFFFFF)
.
static address_v4 broadcast(const address_v4& addr, const address_v4& mask);
Returns:
address_v4(addr.to_ulong() | ~mask.to_ulong())
.
static address_v4 netmask(const address_v4& addr);
If
addr.is_class_a()
is true, returnsaddress_v4(0xFF000000)
. Ifaddr.is_class_b()
is true, returnsaddress_v4(0xFFFF0000)
. Ifaddr.is_class_c()
is true, returnsaddress_v4(0xFFFFFF00)
. Otherwise returnsaddress_v4(0xFFFFFFFF)
.
bool operator==(const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() == b.to_ulong()
.
bool operator!=(const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() != b.to_ulong()
.
bool operator< (const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() < b.to_ulong()
.
bool operator> (const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() > b.to_ulong()
.
bool operator<=(const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() <= b.to_ulong()
.
bool operator>=(const address_v4& a, const address_v4& b);
Returns:
a.to_ulong() >= b.to_ulong()
.
template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address_v4& addr);
Effects: Outputs the string representation of the address to the stream, as if it were implemented as follows:
error_code ec; string s = addr.to_string(ec); if (ec) { if (os.exceptions() & ios_base::failbit) throw system_error(ec); else os.setstate(ios_base::failbit); } else for (string::iterator i = s.begin(); i != s.end(); ++i) os << os.widen(*i);
Returns:
os
.
namespace std { namespace net { namespace ip { class address_v6 { public: // types: typedef array<unsigned char, 16> bytes_type; // constructors: address_v6(); explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0); // members: void scope_id(unsigned long id); unsigned long scope_id() const; bool is_unspecified() const; bool is_loopback() const; bool is_multicast() const; bool is_link_local() const; bool is_site_local() const; bool is_v4_mapped() const; bool is_v4_compatible() const; bool is_multicast_node_local() const; bool is_multicast_link_local() const; bool is_multicast_site_local() const; bool is_multicast_org_local() const; bool is_multicast_global() const; bytes_type to_bytes() const; string to_string() const; string to_string(error_code& ec) const; address_v4 to_v4() const; // static members: static address_v6 from_string(const string& str); static address_v6 from_string(const string& str, error_code& ec); static address_v6 any(); static address_v6 loopback(); static address_v6 v4_mapped(const address_v4& addr); static address_v6 v4_compatible(const address_v4& addr); }; // address_v6 comparisons: bool operator==(const address_v6& a, const address_v6& b); bool operator!=(const address_v6& a, const address_v6& b); bool operator< (const address_v6& a, const address_v6& b); bool operator> (const address_v6& a, const address_v6& b); bool operator<=(const address_v6& a, const address_v6& b); bool operator>=(const address_v6& a, const address_v6& b); // address_v6 I/O: template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address_v6& addr); } // namespace ip } // namespace net } // namespace std
[Note: The implementations of the functions is_unspecified
, is_loopback
,
is_multicast
, is_link_local
, is_site_local
,
is_v4_mapped
, is_v4_compatible
, is_multicast_node_local
,
is_multicast_link_local
,
is_multicast_site_local
,
is_multicast_org_local
and is_multicast_global
are determined by [RFC4291]. —end
note]
address_v6();
Effects: Constructs an object of class
address_v6
.
Postconditions: The postconditions of this function are indicated in the table below.
explicit address_v6(const bytes_type& bytes, unsigned long scope_id = 0);
Effects: Constructs an object of class
address_v6
.
Postconditions: The postconditions of this function are indicated in the table below.
void scope_id(unsigned long id);
Postconditions:
scope_id() == id
.
unsigned long scope_id() const;
Returns: The scope identifier associated with the address.
bool is_unspecified() const;
Returns: A boolean indicating whether the
address_v6
object represents an unspecified address, as if computed by the following method:bytes_type b = to_bytes(); return b[ 0] == 0 && b[ 1] == 0 && b[ 2] == 0 && b[ 3] == 0 && b[ 4] == 0 && b[ 5] == 0 && b[ 6] == 0 && b[ 7] == 0 && b[ 8] == 0 && b[ 9] == 0 && b[10] == 0 && b[11] == 0 && b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 0;
bool is_loopback() const;
Returns: A boolean indicating whether the
address_v6
object represents a loopback address, as if computed by the following method:bytes_type b = to_bytes(); return b[ 0] == 0 && b[ 1] == 0 && b[ 2] == 0 && b[ 3] == 0 && b[ 4] == 0 && b[ 5] == 0 && b[ 6] == 0 && b[ 7] == 0 && b[ 8] == 0 && b[ 9] == 0 && b[10] == 0 && b[11] == 0 && b[12] == 0 && b[13] == 0 && b[14] == 0 && b[15] == 1;
bool is_multicast() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF;
bool is_link_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a unicast link-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFE && (b[1] & 0xC0) == 0x80;
bool is_site_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a unicast site-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFE && (b[1] & 0xC0) == 0xC0;
bool is_v4_mapped() const;
Returns: A boolean indicating whether the
address_v6
object represents an IPv4-mapped IPv6 address, as if computed by the following method:bytes_type b = to_bytes(); return b[ 0] == 0 && b[ 1] == 0 && b[ 2] == 0 && b[ 3] == 0 && b[ 4] == 0 && b[ 5] == 0 && b[ 6] == 0 && b[ 7] == 0 && b[ 8] == 0 && b[ 9] == 0 && b[10] == 0xFF && b[11] == 0xFF;
bool is_v4_compatible() const;
Returns: A boolean indicating whether the
address_v6
object represents an IPv4-compatible IPv6 address, as if computed by the following method:bytes_type b = to_bytes(); return b[ 0] == 0 && b[ 1] == 0 && b[ 2] == 0 && b[ 3] == 0 && b[ 4] == 0 && b[ 5] == 0 && b[ 6] == 0 && b[ 7] == 0 && b[ 8] == 0 && b[ 9] == 0 && b[10] == 0 && b[11] == 0 && !is_unspecified() && !is_loopback();
bool is_multicast_node_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast node-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF && (b[1] & 0x0F) == 0x01;
bool is_multicast_link_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast link-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF && (b[1] & 0x0F) == 0x02;
bool is_multicast_site_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast site-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF && (b[1] & 0x0F) == 0x05;
bool is_multicast_org_local() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast organisation-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF && (b[1] & 0x0F) == 0x08;
bool is_multicast_global() const;
Returns: A boolean indicating whether the
address_v6
object represents a multicast organisation-local address, as if computed by the following method:bytes_type b = to_bytes(); return b[0] == 0xFF && (b[1] & 0x0F) == 0x0E;
bytes_type to_bytes() const;
Returns: A representation of the address in network byte order.
string to_string() const; string to_string(error_code& ec) const;
Effects: Converts an address into a string representation. If
scope_id() == 0
, converts as if by POSIXinet_ntop()
when invoked with address familyAF_INET6
. Ifscope_id() != 0
, the format isaddress
%
scope-id
, whereaddress
is the string representation of the equivalent address havingscope_id() == 0
, andscope-id
is an implementation-defined string representation of the scope identifier.
Returns: If successful, the string representation of the address. Otherwise
string()
.
address_v4 to_v4() const;
Requires:
is_v4_mapped() || is_v4_compatible()
.
Returns: An
address_v4
object corresponding to the IPv4-mapped or IPv4 compatible IPv6 address, as if computed by the following method:bytes_type v6b = to_bytes(); address_v4::bytes_type v4b = { v6b[12], v6b[13], v6b[14], v6b[15] }; return address_v4(v4b);
Throws:
bad_cast
ifis_v4_mapped()
isfalse
andis_v4_compatible()
isfalse
.
static address_v6 from_string(const string& str); static address_v6 from_string(const string& str, error_code& ec);
Effects: Converts a string representation of an address into a corresponding
address_v6
value. The format is eitheraddress
oraddress
%
scope-id
, whereaddress
is in the format specified by POSIXinet_pton()
when invoked with address familyAF_INET6
, andscope-id
is an optional string specifying the scope identifier. All implementations shall accept asscope-id
a string representation of an unsigned decimal integer. It is implementation-defined whether alternative scope identifier representations are permitted. Ifscope-id
is not supplied, anaddress_v6
object shall be returned such thatscope_id() == 0
.
Returns: If successful, an
address_v6
value corresponding to the stringstr
. Otherwise returnsaddress_v6()
.
static address_v6 any();
Returns:
address_v6()
.
static address_v6 loopback();
Returns: An address
a
such that the conditiona.is_loopback()
holds.
static address_v6 v4_mapped(const address_v4& addr);
Returns: An
address_v6
object containing the IPv4-mapped IPv6 address corresponding to the specified IPv4 address, as if computed by the following method:address_v4::bytes_type v4b = addr.to_bytes(); bytes_type v6b = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, v4b[0], v4b[1], v4b[2], v4b[3] }; return address_v6(v6b);
static address_v6 v4_compatible(const address_v4& addr);
Returns: An
address_v6
object containing the IPv4-compatible IPv6 address corresponding to the specified IPv4 address, as if computed by the following method:address_v4::bytes_type v4b = addr.to_bytes(); bytes_type v6b = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, v4b[0], v4b[1], v4b[2], v4b[3] }; return address_v6(v6b);
bool operator==(const address_v6& a, const address_v6& b);
Returns:
a.to_bytes() == b.to_bytes() && a.scope_id() == b.scope_id()
.
bool operator!=(const address_v6& a, const address_v6& b);
Returns:
!(a == b)
.
bool operator< (const address_v6& a, const address_v6& b);
Returns:
a.to_bytes() < b.to_bytes() || (!(b.to_bytes() < a.to_bytes()) && a.scope_id() < b.scope_id())
.
bool operator> (const address_v6& a, const address_v6& b);
Returns:
b < a
.
bool operator<=(const address_v6& a, const address_v6& b);
Returns:
!(b < a)
.
bool operator>=(const address_v6& a, const address_v6& b);
Returns:
!(a < b)
.
template<class CharT, class Traits> basic_ostream<CharT, Traits>& operator<<( basic_ostream<CharT, Traits>& os, const address_v6& addr);
Effects: Outputs the string representation of the address to the stream, as if it were implemented as follows:
error_code ec; string s = addr.to_string(ec); if (ec) { if (os.exceptions() & ios_base::failbit) throw system_error(ec); else os.setstate(ios_base::failbit); } else for (string::iterator i = s.begin(); i != s.end(); ++i) os << os.widen(*i);
Returns:
os
.
The author would like to thank Arash Partow, Jamie Allsop and James Anderson for their feedback and suggestions.
[RFC4291] Hinden, R. and Deering, S., RFC 4291: Internet Protocol Version 6 (IPv6) Addressing Architecture, 2006, http://www.ietf.org/rfc/rfc4291.txt.