1 | #ifndef IP_ADDRESS_HPP_ |
---|
2 | #define IP_ADDRESS_HPP_ |
---|
3 | |
---|
4 | #include <string> |
---|
5 | #include <boost/tr1/functional.hpp> |
---|
6 | #include <boost/asio/ip/address.hpp> |
---|
7 | |
---|
8 | #include "detail/address_convenience.hpp" |
---|
9 | |
---|
10 | namespace ariba { |
---|
11 | namespace addressing { |
---|
12 | |
---|
13 | using boost::asio::ip::address; |
---|
14 | using boost::asio::ip::address_v4; |
---|
15 | using boost::asio::ip::address_v6; |
---|
16 | |
---|
17 | /** |
---|
18 | * TODO: Doc |
---|
19 | * |
---|
20 | * @author Sebastian Mies <mies@tm.uka.de> |
---|
21 | */ |
---|
22 | class ip_address: public detail::address_convenience<ip_address> { |
---|
23 | private: |
---|
24 | address addr; |
---|
25 | static const std::string type_name_ip; |
---|
26 | |
---|
27 | public: |
---|
28 | ip_address() : addr() { |
---|
29 | } |
---|
30 | |
---|
31 | ip_address(const ip_address& copy) : addr(copy.addr) { |
---|
32 | |
---|
33 | } |
---|
34 | |
---|
35 | ip_address(const address& addr) : addr(addr) { |
---|
36 | |
---|
37 | } |
---|
38 | |
---|
39 | ip_address(const address_v4& addr) : addr(addr) { |
---|
40 | |
---|
41 | } |
---|
42 | |
---|
43 | ip_address(const address_v6& addr) : addr(addr) { |
---|
44 | |
---|
45 | } |
---|
46 | |
---|
47 | ip_address(const std::string& text) { |
---|
48 | assign(text); |
---|
49 | } |
---|
50 | |
---|
51 | ip_address(const char* text) { |
---|
52 | assign(std::string(text)); |
---|
53 | } |
---|
54 | |
---|
55 | ip_address(const uint8_t* bytes, size_t size) { |
---|
56 | assign(bytes, size); |
---|
57 | } |
---|
58 | |
---|
59 | //--- compare operations -------------------------------------------------- |
---|
60 | |
---|
61 | /// implements comparison operators |
---|
62 | int compare_to(const ip_address& rhs) const { |
---|
63 | if (addr == rhs.addr) return 0; |
---|
64 | if (addr < rhs.addr) return -1; else return 1; |
---|
65 | } |
---|
66 | |
---|
67 | //--- byte representation ------------------------------------------------- |
---|
68 | |
---|
69 | /// returns true, if this address has a fixed size in bytes |
---|
70 | bool is_bytes_size_static() const { |
---|
71 | return false; |
---|
72 | } |
---|
73 | |
---|
74 | /// returns the number of bytes used for serialization of this address |
---|
75 | size_t to_bytes_size() const { |
---|
76 | return addr.is_v4() ? 4 : 16; |
---|
77 | } |
---|
78 | |
---|
79 | /// converts this address to a binary representation |
---|
80 | void to_bytes(uint8_t* bytes) const { |
---|
81 | if (addr.is_v4()) { |
---|
82 | address_v4::bytes_type bytes_ = addr.to_v4().to_bytes(); |
---|
83 | for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i]; |
---|
84 | } else { |
---|
85 | address_v6::bytes_type bytes_ = addr.to_v6().to_bytes(); |
---|
86 | for (size_t i=0; i<bytes_.size(); i++) bytes[i] = bytes_[i]; |
---|
87 | } |
---|
88 | } |
---|
89 | |
---|
90 | /// Assigns an address using a bunch of bytes |
---|
91 | bool assign(const uint8_t* bytes, size_t size) { |
---|
92 | if (size == 4) { |
---|
93 | address_v4::bytes_type bytes_; |
---|
94 | for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i]; |
---|
95 | addr = address_v4(bytes_); |
---|
96 | return false; |
---|
97 | } else |
---|
98 | if (size == 16) { |
---|
99 | address_v6::bytes_type bytes_; |
---|
100 | for (size_t i=0; i<bytes_.size(); i++) bytes_[i] = bytes[i]; |
---|
101 | addr = address_v6(bytes_); |
---|
102 | return false; |
---|
103 | } |
---|
104 | return true; |
---|
105 | } |
---|
106 | |
---|
107 | //--- string representation ----------------------------------------------- |
---|
108 | |
---|
109 | /// convert address to a string that can be used to reconstruct the address |
---|
110 | std::string to_string() const { |
---|
111 | return addr.to_string(); |
---|
112 | } |
---|
113 | |
---|
114 | /// Assigns an address using a human-readable |
---|
115 | bool assign(const std::string& text) { |
---|
116 | addr = address::from_string(text); |
---|
117 | return false; |
---|
118 | } |
---|
119 | |
---|
120 | //--- assignment ---------------------------------------------------------- |
---|
121 | |
---|
122 | /// Assigns an address |
---|
123 | bool assign(const ip_address& rhs) { |
---|
124 | addr = rhs.addr; |
---|
125 | return false; |
---|
126 | } |
---|
127 | |
---|
128 | //--- address info -------------------------------------------------------- |
---|
129 | |
---|
130 | static const std::string& type_name() { |
---|
131 | return type_name_ip; |
---|
132 | } |
---|
133 | |
---|
134 | static const uint16_t type_id() { |
---|
135 | return 0x81DD; |
---|
136 | } |
---|
137 | |
---|
138 | //--- address delegates --------------------------------------------------- |
---|
139 | |
---|
140 | bool is_multicast() const { |
---|
141 | if (addr.is_v4()) return addr.to_v4().is_multicast(); |
---|
142 | return addr.to_v6().is_multicast(); |
---|
143 | } |
---|
144 | |
---|
145 | bool is_loopback() const { |
---|
146 | if (addr.is_v4()) return addr.to_v4() == address_v4::loopback(); |
---|
147 | return addr.to_v6().is_loopback(); |
---|
148 | } |
---|
149 | |
---|
150 | bool is_link_local() const { |
---|
151 | if (addr.is_v4()) return false; |
---|
152 | return addr.to_v6().is_link_local(); |
---|
153 | } |
---|
154 | |
---|
155 | bool is_multicast_link_local() const { |
---|
156 | if (addr.is_v4()) return false; |
---|
157 | return addr.to_v6().is_multicast_link_local(); |
---|
158 | |
---|
159 | } |
---|
160 | |
---|
161 | bool is_multicast_node_local() const { |
---|
162 | if (addr.is_v4()) return false; |
---|
163 | return addr.to_v6().is_multicast_node_local(); |
---|
164 | } |
---|
165 | |
---|
166 | |
---|
167 | bool is_multicast_site_local() const { |
---|
168 | if (addr.is_v4()) return false; |
---|
169 | return addr.to_v6().is_multicast_site_local(); |
---|
170 | } |
---|
171 | |
---|
172 | bool is_any() const { |
---|
173 | if (addr.is_v4()) return addr.to_v4() == address_v4::any(); |
---|
174 | return addr.to_v6() == address_v6::any(); |
---|
175 | } |
---|
176 | |
---|
177 | bool is_v4_compatible() const { |
---|
178 | if (addr.is_v4()) return true; |
---|
179 | return addr.to_v6().is_v4_compatible(); |
---|
180 | } |
---|
181 | |
---|
182 | bool is_v4_mapped() { |
---|
183 | if (addr.is_v4()) return true; |
---|
184 | return addr.to_v6().is_v4_mapped(); |
---|
185 | } |
---|
186 | |
---|
187 | bool is_v4() const { |
---|
188 | return addr.is_v4(); |
---|
189 | } |
---|
190 | |
---|
191 | bool is_v6() const { |
---|
192 | return addr.is_v6(); |
---|
193 | } |
---|
194 | |
---|
195 | //--- address conversions ------------------------------------------------- |
---|
196 | |
---|
197 | const address& asio() const { |
---|
198 | return addr; |
---|
199 | } |
---|
200 | |
---|
201 | void asio( const address& addr ) { |
---|
202 | this->addr = addr; |
---|
203 | } |
---|
204 | }; |
---|
205 | |
---|
206 | }} // namespace ariba::addressing |
---|
207 | |
---|
208 | namespace boost { |
---|
209 | |
---|
210 | // boost hash function |
---|
211 | template<> |
---|
212 | struct hash<ariba::addressing::ip_address>: public std::unary_function<ariba::addressing::ip_address, std::size_t> { |
---|
213 | std::size_t operator()(const ariba::addressing::ip_address& ep) const { |
---|
214 | return hash_value(ep.to_string()); |
---|
215 | } |
---|
216 | }; |
---|
217 | |
---|
218 | } |
---|
219 | |
---|
220 | |
---|
221 | #endif /* IP_ADDRESS_HPP_ */ |
---|