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 ip_address(const address& addr) : addr(addr) {
00035
00036 }
00037
00038 ip_address(const address_v4& addr) : addr(addr) {
00039
00040 }
00041
00042 ip_address(const address_v6& addr) : addr(addr) {
00043
00044 }
00045
00046 ip_address(const std::string& text) {
00047 assign(text);
00048 }
00049
00050 ip_address(const char* text) {
00051 assign(std::string(text));
00052 }
00053
00054 ip_address(const uint8_t* bytes, size_t size) {
00055 assign(bytes, size);
00056 }
00057
00058
00059
00061 int compare_to(const ip_address& rhs) const {
00062 if (addr == rhs.addr) return 0;
00063 if (addr < rhs.addr) return -1; else return 1;
00064 }
00065
00066
00067
00069 bool is_bytes_size_static() const {
00070 return false;
00071 }
00072
00074 size_t to_bytes_size() const {
00075 return addr.is_v4() ? 4 : 16;
00076 }
00077
00079 void to_bytes(uint8_t* bytes) const {
00080 if (addr.is_v4()) {
00081 address_v4::bytes_type bytes_ = addr.to_v4().to_bytes();
00082 for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i];
00083 } else {
00084 address_v6::bytes_type bytes_ = addr.to_v6().to_bytes();
00085 for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i];
00086 }
00087 }
00088
00090 bool assign(const uint8_t* bytes, size_t size) {
00091 if (size == 4) {
00092 address_v4::bytes_type bytes_;
00093 for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i];
00094 addr = address_v4(bytes_);
00095 return false;
00096 } else
00097 if (size == 16) {
00098 address_v6::bytes_type bytes_;
00099 for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i];
00100 addr = address_v6(bytes_);
00101 return false;
00102 }
00103 return true;
00104 }
00105
00106
00107
00109 std::string to_string() const {
00110 if (addr.is_v6() && (addr.to_v6().is_v4_compatible()
00111 || addr.to_v6().is_v4_mapped()))
00112 return addr.to_v6().to_v4().to_string();
00113 return addr.to_string();
00114 }
00115
00117 bool assign(const std::string& text) {
00118 addr = address::from_string(text);
00119 return false;
00120 }
00121
00122
00123
00125 bool assign(const ip_address& rhs) {
00126 addr = rhs.addr;
00127 return false;
00128 }
00129
00130
00131
00132 static const std::string& type_name() {
00133 return type_name_ip;
00134 }
00135
00136 static const uint16_t type_id() {
00137 return 0x81DD;
00138 }
00139
00140
00141
00142 bool is_multicast() const {
00143 if (addr.is_v4()) return addr.to_v4().is_multicast();
00144 return addr.to_v6().is_multicast();
00145 }
00146
00147 bool is_loopback() const {
00148 if (addr.is_v4()) return addr.to_v4() == address_v4::loopback();
00149 return addr.to_v6().is_loopback();
00150 }
00151
00152 bool is_link_local() const {
00153 if (addr.is_v4()) return false;
00154 return addr.to_v6().is_link_local();
00155 }
00156
00157 bool is_multicast_link_local() const {
00158 if (addr.is_v4()) return false;
00159 return addr.to_v6().is_multicast_link_local();
00160
00161 }
00162
00163 bool is_multicast_node_local() const {
00164 if (addr.is_v4()) return false;
00165 return addr.to_v6().is_multicast_node_local();
00166 }
00167
00168 bool is_multicast_site_local() const {
00169 if (addr.is_v4()) return false;
00170 return addr.to_v6().is_multicast_site_local();
00171 }
00172
00173 bool is_any() const {
00174 if (addr.is_v4()) return addr.to_v4() == address_v4::any();
00175 return addr.to_v6() == address_v6::any();
00176 }
00177
00178 bool is_v4_compatible() const {
00179 if (addr.is_v4()) return true;
00180 return addr.to_v6().is_v4_compatible();
00181 }
00182
00183 bool is_v4_mapped() {
00184 if (addr.is_v4()) return true;
00185 return addr.to_v6().is_v4_mapped();
00186 }
00187
00188 bool is_v4() const {
00189 return addr.is_v4();
00190 }
00191
00192 bool is_v6() const {
00193 return addr.is_v6();
00194 }
00195
00196
00197
00198 const address& asio() const {
00199 return addr;
00200 }
00201
00202 void asio( const address& addr ) {
00203 this->addr = addr;
00204 }
00205 };
00206
00207 }}
00208
00209 namespace boost {
00210
00211
00212 template<>
00213 struct hash<ariba::addressing::ip_address>: public std::unary_function<ariba::addressing::ip_address, std::size_t> {
00214 std::size_t operator()(const ariba::addressing::ip_address& ep) const {
00215 return hash_value(ep.to_string());
00216 }
00217 };
00218
00219 }
00220
00221
00222 #endif