Home | History | Annotate | Download | only in impl
      1 //
      2 // ip/impl/address_v4.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_IMPL_ADDRESS_V4_IPP
     12 #define ASIO_IP_IMPL_ADDRESS_V4_IPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include <climits>
     17 #include <stdexcept>
     18 #include "asio/error.hpp"
     19 #include "asio/detail/socket_ops.hpp"
     20 #include "asio/detail/throw_error.hpp"
     21 #include "asio/detail/throw_exception.hpp"
     22 #include "asio/ip/address_v4.hpp"
     23 
     24 #include "asio/detail/push_options.hpp"
     25 
     26 namespace asio {
     27 namespace ip {
     28 
     29 address_v4::address_v4(const address_v4::bytes_type& bytes)
     30 {
     31 #if UCHAR_MAX > 0xFF
     32   if (bytes[0] > 0xFF || bytes[1] > 0xFF
     33       || bytes[2] > 0xFF || bytes[3] > 0xFF)
     34   {
     35     std::out_of_range ex("address_v4 from bytes_type");
     36     asio::detail::throw_exception(ex);
     37   }
     38 #endif // UCHAR_MAX > 0xFF
     39 
     40   using namespace std; // For memcpy.
     41   memcpy(&addr_.s_addr, bytes.data(), 4);
     42 }
     43 
     44 address_v4::address_v4(unsigned long addr)
     45 {
     46 #if ULONG_MAX > 0xFFFFFFFF
     47   if (addr > 0xFFFFFFFF)
     48   {
     49     std::out_of_range ex("address_v4 from unsigned long");
     50     asio::detail::throw_exception(ex);
     51   }
     52 #endif // ULONG_MAX > 0xFFFFFFFF
     53 
     54   addr_.s_addr = asio::detail::socket_ops::host_to_network_long(
     55       static_cast<asio::detail::u_long_type>(addr));
     56 }
     57 
     58 address_v4::bytes_type address_v4::to_bytes() const
     59 {
     60   using namespace std; // For memcpy.
     61   bytes_type bytes;
     62   memcpy(bytes.data(), &addr_.s_addr, 4);
     63   return bytes;
     64 }
     65 
     66 unsigned long address_v4::to_ulong() const
     67 {
     68   return asio::detail::socket_ops::network_to_host_long(addr_.s_addr);
     69 }
     70 
     71 std::string address_v4::to_string() const
     72 {
     73   asio::error_code ec;
     74   std::string addr = to_string(ec);
     75   asio::detail::throw_error(ec);
     76   return addr;
     77 }
     78 
     79 std::string address_v4::to_string(asio::error_code& ec) const
     80 {
     81   char addr_str[asio::detail::max_addr_v4_str_len];
     82   const char* addr =
     83     asio::detail::socket_ops::inet_ntop(
     84         ASIO_OS_DEF(AF_INET), &addr_, addr_str,
     85         asio::detail::max_addr_v4_str_len, 0, ec);
     86   if (addr == 0)
     87     return std::string();
     88   return addr;
     89 }
     90 
     91 address_v4 address_v4::from_string(const char* str)
     92 {
     93   asio::error_code ec;
     94   address_v4 addr = from_string(str, ec);
     95   asio::detail::throw_error(ec);
     96   return addr;
     97 }
     98 
     99 address_v4 address_v4::from_string(
    100     const char* str, asio::error_code& ec)
    101 {
    102   address_v4 tmp;
    103   if (asio::detail::socket_ops::inet_pton(
    104         ASIO_OS_DEF(AF_INET), str, &tmp.addr_, 0, ec) <= 0)
    105     return address_v4();
    106   return tmp;
    107 }
    108 
    109 address_v4 address_v4::from_string(const std::string& str)
    110 {
    111   return from_string(str.c_str());
    112 }
    113 
    114 address_v4 address_v4::from_string(
    115     const std::string& str, asio::error_code& ec)
    116 {
    117   return from_string(str.c_str(), ec);
    118 }
    119 
    120 bool address_v4::is_loopback() const
    121 {
    122   return (to_ulong() & 0xFF000000) == 0x7F000000;
    123 }
    124 
    125 bool address_v4::is_unspecified() const
    126 {
    127   return to_ulong() == 0;
    128 }
    129 
    130 bool address_v4::is_class_a() const
    131 {
    132   return (to_ulong() & 0x80000000) == 0;
    133 }
    134 
    135 bool address_v4::is_class_b() const
    136 {
    137   return (to_ulong() & 0xC0000000) == 0x80000000;
    138 }
    139 
    140 bool address_v4::is_class_c() const
    141 {
    142   return (to_ulong() & 0xE0000000) == 0xC0000000;
    143 }
    144 
    145 bool address_v4::is_multicast() const
    146 {
    147   return (to_ulong() & 0xF0000000) == 0xE0000000;
    148 }
    149 
    150 address_v4 address_v4::broadcast(const address_v4& addr, const address_v4& mask)
    151 {
    152   return address_v4(addr.to_ulong() | (mask.to_ulong() ^ 0xFFFFFFFF));
    153 }
    154 
    155 address_v4 address_v4::netmask(const address_v4& addr)
    156 {
    157   if (addr.is_class_a())
    158     return address_v4(0xFF000000);
    159   if (addr.is_class_b())
    160     return address_v4(0xFFFF0000);
    161   if (addr.is_class_c())
    162     return address_v4(0xFFFFFF00);
    163   return address_v4(0xFFFFFFFF);
    164 }
    165 
    166 } // namespace ip
    167 } // namespace asio
    168 
    169 #include "asio/detail/pop_options.hpp"
    170 
    171 #endif // ASIO_IP_IMPL_ADDRESS_V4_IPP
    172