1// 2// ip/detail/impl/endpoint.ipp 3// ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 4// 5// Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) 6// 7// Distributed under the Boost Software License, Version 1.0. (See accompanying 8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 9// 10 11#ifndef ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP 12#define ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP 13 14 15#include "asio/detail/config.hpp" 16#include <cstring> 17#include "asio/detail/socket_ops.hpp" 18#include "asio/detail/throw_error.hpp" 19#include "asio/error.hpp" 20#include "asio/ip/detail/endpoint.hpp" 21 22#include "asio/detail/push_options.hpp" 23 24namespace asio { 25namespace ip { 26namespace detail { 27 28endpoint::endpoint() 29 : data_() 30{ 31 data_.v4.sin_family = ASIO_OS_DEF(AF_INET); 32 data_.v4.sin_port = 0; 33 data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); 34} 35 36endpoint::endpoint(int family, unsigned short port_num) 37 : data_() 38{ 39 using namespace std; // For memcpy. 40 if (family == ASIO_OS_DEF(AF_INET)) 41 { 42 data_.v4.sin_family = ASIO_OS_DEF(AF_INET); 43 data_.v4.sin_port = 44 asio::detail::socket_ops::host_to_network_short(port_num); 45 data_.v4.sin_addr.s_addr = ASIO_OS_DEF(INADDR_ANY); 46 } 47 else 48 { 49 data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); 50 data_.v6.sin6_port = 51 asio::detail::socket_ops::host_to_network_short(port_num); 52 data_.v6.sin6_flowinfo = 0; 53 data_.v6.sin6_addr.s6_addr[0] = 0; data_.v6.sin6_addr.s6_addr[1] = 0; 54 data_.v6.sin6_addr.s6_addr[2] = 0, data_.v6.sin6_addr.s6_addr[3] = 0; 55 data_.v6.sin6_addr.s6_addr[4] = 0, data_.v6.sin6_addr.s6_addr[5] = 0; 56 data_.v6.sin6_addr.s6_addr[6] = 0, data_.v6.sin6_addr.s6_addr[7] = 0; 57 data_.v6.sin6_addr.s6_addr[8] = 0, data_.v6.sin6_addr.s6_addr[9] = 0; 58 data_.v6.sin6_addr.s6_addr[10] = 0, data_.v6.sin6_addr.s6_addr[11] = 0; 59 data_.v6.sin6_addr.s6_addr[12] = 0, data_.v6.sin6_addr.s6_addr[13] = 0; 60 data_.v6.sin6_addr.s6_addr[14] = 0, data_.v6.sin6_addr.s6_addr[15] = 0; 61 data_.v6.sin6_scope_id = 0; 62 } 63} 64 65endpoint::endpoint(const asio::ip::address& addr, 66 unsigned short port_num) 67 : data_() 68{ 69 using namespace std; // For memcpy. 70 if (addr.is_v4()) 71 { 72 data_.v4.sin_family = ASIO_OS_DEF(AF_INET); 73 data_.v4.sin_port = 74 asio::detail::socket_ops::host_to_network_short(port_num); 75 data_.v4.sin_addr.s_addr = 76 asio::detail::socket_ops::host_to_network_long( 77 static_cast<asio::detail::u_long_type>( 78 addr.to_v4().to_ulong())); 79 } 80 else 81 { 82 data_.v6.sin6_family = ASIO_OS_DEF(AF_INET6); 83 data_.v6.sin6_port = 84 asio::detail::socket_ops::host_to_network_short(port_num); 85 data_.v6.sin6_flowinfo = 0; 86 asio::ip::address_v6 v6_addr = addr.to_v6(); 87 asio::ip::address_v6::bytes_type bytes = v6_addr.to_bytes(); 88 memcpy(data_.v6.sin6_addr.s6_addr, bytes.data(), 16); 89 data_.v6.sin6_scope_id = 90 static_cast<asio::detail::u_long_type>( 91 v6_addr.scope_id()); 92 } 93} 94 95void endpoint::resize(std::size_t new_size) 96{ 97 if (new_size > sizeof(asio::detail::sockaddr_storage_type)) 98 { 99 asio::error_code ec(asio::error::invalid_argument); 100 asio::detail::throw_error(ec); 101 } 102} 103 104unsigned short endpoint::port() const 105{ 106 if (is_v4()) 107 { 108 return asio::detail::socket_ops::network_to_host_short( 109 data_.v4.sin_port); 110 } 111 else 112 { 113 return asio::detail::socket_ops::network_to_host_short( 114 data_.v6.sin6_port); 115 } 116} 117 118void endpoint::port(unsigned short port_num) 119{ 120 if (is_v4()) 121 { 122 data_.v4.sin_port 123 = asio::detail::socket_ops::host_to_network_short(port_num); 124 } 125 else 126 { 127 data_.v6.sin6_port 128 = asio::detail::socket_ops::host_to_network_short(port_num); 129 } 130} 131 132asio::ip::address endpoint::address() const 133{ 134 using namespace std; // For memcpy. 135 if (is_v4()) 136 { 137 return asio::ip::address_v4( 138 asio::detail::socket_ops::network_to_host_long( 139 data_.v4.sin_addr.s_addr)); 140 } 141 else 142 { 143 asio::ip::address_v6::bytes_type bytes; 144 memcpy(bytes.data(), data_.v6.sin6_addr.s6_addr, 16); 145 return asio::ip::address_v6(bytes, data_.v6.sin6_scope_id); 146 } 147} 148 149void endpoint::address(const asio::ip::address& addr) 150{ 151 endpoint tmp_endpoint(addr, port()); 152 data_ = tmp_endpoint.data_; 153} 154 155bool operator==(const endpoint& e1, const endpoint& e2) 156{ 157 return e1.address() == e2.address() && e1.port() == e2.port(); 158} 159 160bool operator<(const endpoint& e1, const endpoint& e2) 161{ 162 if (e1.address() < e2.address()) 163 return true; 164 if (e1.address() != e2.address()) 165 return false; 166 return e1.port() < e2.port(); 167} 168 169 170} // namespace detail 171} // namespace ip 172} // namespace asio 173 174#include "asio/detail/pop_options.hpp" 175 176#endif // ASIO_IP_DETAIL_IMPL_ENDPOINT_IPP 177