00001 #ifndef IP_ADDRESS_HPP_
00002 #define IP_ADDRESS_HPP_
00003
00004 #include <string>
00005 #include <boost/tr1/functional.hpp>
00006 #include <boost/asio/ip/address.hpp>
00007
00008 #include "detail/address_convenience.hpp"
00009
00010 namespace ariba {
00011 namespace addressing {
00012
00013 using boost::asio::ip::address;
00014 using boost::asio::ip::address_v4;
00015 using boost::asio::ip::address_v6;
00016
00022 class ip_address: public detail::address_convenience<ip_address> {
00023 private:
00024 address addr;
00025 static const std::string type_name_ip;
00026
00027 public:
00028 ip_address() : addr() {
00029 }
00030
00031 ip_address(const ip_address& copy) : addr(copy.addr) {
00032
00033 }
00034
00035 ip_address(const address& addr) : addr(addr) {
00036
00037 }
00038
00039 ip_address(const address_v4& addr) : addr(addr) {
00040
00041 }
00042
00043 ip_address(const address_v6& addr) : addr(addr) {
00044
00045 }
00046
00047 ip_address(const std::string& text) {
00048 assign(text);
00049 }
00050
00051 ip_address(const char* text) {
00052 assign(std::string(text));
00053 }
00054
00055 ip_address(const uint8_t* bytes, size_t size) {
00056 assign(bytes, size);
00057 }
00058
00059
00060
00062 int compare_to(const ip_address& rhs) const {
00063 if (addr == rhs.addr) return 0;
00064 if (addr < rhs.addr) return -1; else return 1;
00065 }
00066
00067
00068
00070 bool is_bytes_size_static() const {
00071 return false;
00072 }
00073
00075 size_t to_bytes_size() const {
00076 return addr.is_v4() ? 4 : 16;
00077 }
00078
00080 void to_bytes(uint8_t* bytes) const {
00081 if (addr.is_v4()) {
00082 address_v4::bytes_type bytes_ = addr.to_v4().to_bytes();
00083 for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i];
00084 } else {
00085 address_v6::bytes_type bytes_ = addr.to_v6().to_bytes();
00086 for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i];
00087 }
00088 }
00089
00091 bool assign(const uint8_t* bytes, size_t size) {
00092 if (size == 4) {
00093 address_v4::bytes_type bytes_;
00094 for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i];
00095 addr = address_v4(bytes_);
00096 return false;
00097 } else
00098 if (size == 16) {
00099 address_v6::bytes_type bytes_;
00100 for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i];
00101 addr = address_v6(bytes_);
00102 return false;
00103 }
00104 return true;
00105 }
00106
00107
00108
00110 std::string to_string() const {
00111 return addr.to_string();
00112 }
00113
00115 bool assign(const std::string& text) {
00116 addr = address::from_string(text);
00117 return false;
00118 }
00119
00120
00121
00123 bool assign(const ip_address& rhs) {
00124 addr = rhs.addr;
00125 return false;
00126 }
00127
00128
00129
00130 static const std::string& type_name() {
00131 return type_name_ip;
00132 }
00133
00134 static const uint16_t type_id() {
00135 return 0x81DD;
00136 }
00137
00138
00139
00140 bool is_multicast() const {
00141 if (addr.is_v4()) return addr.to_v4().is_multicast();
00142 return addr.to_v6().is_multicast();
00143 }
00144
00145 bool is_loopback() const {
00146 if (addr.is_v4()) return addr.to_v4() == address_v4::loopback();
00147 return addr.to_v6().is_loopback();
00148 }
00149
00150 bool is_link_local() const {
00151 if (addr.is_v4()) return false;
00152 return addr.to_v6().is_link_local();
00153 }
00154
00155 bool is_multicast_link_local() const {
00156 if (addr.is_v4()) return false;
00157 return addr.to_v6().is_multicast_link_local();
00158
00159 }
00160
00161 bool is_multicast_node_local() const {
00162 if (addr.is_v4()) return false;
00163 return addr.to_v6().is_multicast_node_local();
00164 }
00165
00166
00167 bool is_multicast_site_local() const {
00168 if (addr.is_v4()) return false;
00169 return addr.to_v6().is_multicast_site_local();
00170 }
00171
00172 bool is_any() const {
00173 if (addr.is_v4()) return addr.to_v4() == address_v4::any();
00174 return addr.to_v6() == address_v6::any();
00175 }
00176
00177 bool is_v4_compatible() const {
00178 if (addr.is_v4()) return true;
00179 return addr.to_v6().is_v4_compatible();
00180 }
00181
00182 bool is_v4_mapped() {
00183 if (addr.is_v4()) return true;
00184 return addr.to_v6().is_v4_mapped();
00185 }
00186
00187 bool is_v4() const {
00188 return addr.is_v4();
00189 }
00190
00191 bool is_v6() const {
00192 return addr.is_v6();
00193 }
00194
00195
00196
00197 const address& asio() const {
00198 return addr;
00199 }
00200
00201 void asio( const address& addr ) {
00202 this->addr = addr;
00203 }
00204 };
00205
00206 }}
00207
00208 namespace boost {
00209
00210
00211 template<>
00212 struct hash<ariba::addressing::ip_address>: public std::unary_function<ariba::addressing::ip_address, std::size_t> {
00213 std::size_t operator()(const ariba::addressing::ip_address& ep) const {
00214 return hash_value(ep.to_string());
00215 }
00216 };
00217
00218 }
00219
00220
00221 #endif