11// This file is a part of the IncludeOS unikernel - www.includeos.org
22//
3- // Copyright 2015-2016 Oslo and Akershus University College of Applied Sciences
3+ // Copyright 2015-2017 Oslo and Akershus University College of Applied Sciences
44// and Alfred Bratterud
55//
66// Licensed under the Apache License, Version 2.0 (the "License");
1515// See the License for the specific language governing permissions and
1616// limitations under the License.
1717
18+ #pragma once
1819#ifndef NET_IP4_ADDR_HPP
1920#define NET_IP4_ADDR_HPP
2021
2122#include < regex>
2223#include < string>
23- #include < net/util.hpp> // byte order
24- #include < gsl/gsl_assert>
24+
25+ #include < common>
26+ #include < net/util.hpp>
2527
2628namespace net {
2729namespace ip4 {
2830
29- class Invalid_address : public std ::runtime_error {
30- using runtime_error::runtime_error;
31- };
32-
33- /* * IP4 address representation */
31+ /* *
32+ * This type is thrown when creating an instance of Addr
33+ * with a std::string that doesn't represent a valid IPv4
34+ * address
35+ */
36+ struct Invalid_address : public std ::runtime_error {
37+ using runtime_error::runtime_error;
38+ }; // < struct Invalid_address
39+
40+ /* *
41+ * IPv4 address representation
42+ */
3443struct Addr {
44+ /* *
45+ * Constructor
46+ *
47+ * Create an IPv4 address object to represent the address <0.0.0.0>
48+ */
49+ Addr () noexcept
50+ : whole{}
51+ {}
3552
36- Addr () : whole(0 ) {} // uninitialized
37- Addr (const uint32_t ipv4_addr)
38- : whole(ipv4_addr) {}
39- Addr (const uint8_t p1, const uint8_t p2, const uint8_t p3, const uint8_t p4)
40- : whole(p1 | (p2 << 8 ) | (p3 << 16 ) | (p4 << 24 )) {}
53+ /* *
54+ * Constructor
55+ *
56+ * Create an IPv4 address using a 32-bit value
57+ *
58+ * @param ipv4_addr
59+ * The 32-bit value representing the IPv4 address
60+ *
61+ * @note The 32-bit value must be in network byte order
62+ */
63+ Addr (const uint32_t ipv4_addr) noexcept
64+ : whole{ipv4_addr}
65+ {}
4166
4267 /* *
43- * @brief Construct an IPv4 address from a {std::string}
44- * object
68+ * Constructor
69+ *
70+ * Create an IPv4 address by specifying each part of the address
4571 *
46- * @note If the {std::string} object doesn't contain a valid
47- * IPv4 representation then the instance will contain the
48- * address -> 0.0.0.0
72+ * @param p1
73+ * The first part of the IPv4 address
4974 *
50- * @param ipv4_addr:
75+ * @param p2
76+ * The second part of the IPv4 address
77+ *
78+ * @param p3
79+ * The third part of the IPv4 address
80+ *
81+ * @param p4
82+ * The fourth part of the IPv4 address
83+ */
84+ Addr (const uint8_t p1, const uint8_t p2, const uint8_t p3, const uint8_t p4) noexcept
85+ : whole(p1 | (p2 << 8 ) | (p3 << 16 ) | (p4 << 24 ))
86+ {}
87+
88+ /* *
89+ * Constructor
90+ *
91+ * Construct an IPv4 address from a {std::string} object
92+ * representing an IPv4 address
93+ *
94+ * @param ipv4_addr
5195 * A {std::string} object representing an IPv4 address
96+ *
97+ * @throws Invalid_address
98+ * IIf the {std::string} object doesn't representing a valid IPv4
99+ * address
52100 */
101+ template <typename = void >
53102 Addr (const std::string& ipv4_addr)
54- : Addr{}
55103 {
56- if (not (ipv4_addr.size () >= 7 && ipv4_addr.size () <= 15 )) // < [7, 15] minimum and maximum address length
57- throw Invalid_address (ipv4_addr + " is not a valid IP" );
104+ if (not (ipv4_addr.size () >= 7 && ipv4_addr.size () <= 15 )) { // < [7, 15] minimum and maximum address length
105+ throw Invalid_address{ipv4_addr + " is not a valid IP" };
106+ }
107+
58108 const static std::regex ipv4_address_pattern
59109 {
60110 " ^\\ s*(25[0–5]|2[0–4]\\ d|[01]?\\ d\\ d?)\\ ."
@@ -66,7 +116,7 @@ struct Addr {
66116 std::smatch ipv4_parts;
67117
68118 if (not std::regex_match (ipv4_addr, ipv4_parts, ipv4_address_pattern)) {
69- throw Invalid_address ( ipv4_addr + " is not a valid IP" ) ;
119+ throw Invalid_address{ ipv4_addr + " is not a valid IP" } ;
70120 }
71121
72122 const auto p1 = static_cast <uint8_t >(std::stoi (ipv4_parts[1 ]));
@@ -77,91 +127,210 @@ struct Addr {
77127 whole = p1 | (p2 << 8 ) | (p3 << 16 ) | (p4 << 24 );
78128 }
79129
80- inline Addr& operator =(const Addr cpy) noexcept {
81- whole = cpy.whole ;
130+ /* *
131+ * Assignment operator
132+ *
133+ * @param other
134+ * The IPv4 address object to assign from
135+ *
136+ * @return The object that invoked this method
137+ */
138+ Addr& operator =(const Addr other) noexcept {
139+ whole = other.whole ;
82140 return *this ;
83141 }
84142
85- /* * Standard comparison operators */
86- bool operator ==(const Addr rhs) const noexcept
87- { return (*this == rhs.whole ); }
143+ /* *
144+ * Operator to check for equality
145+ *
146+ * @param other
147+ * The IPv4 address object to check for equality
148+ *
149+ * @return true if this object is equal to other, false otherwise
150+ */
151+ bool operator ==(const Addr other) const noexcept
152+ { return whole == other.whole ; }
88153
89- bool operator ==(const uint32_t rhs) const noexcept
90- { return whole == rhs; }
154+ /* *
155+ * Operator to check for equality
156+ *
157+ * @param raw_addr
158+ * The 32-bit value to check for equality
159+ *
160+ * @return true if this object is equal to raw_addr, false otherwise
161+ *
162+ * @note The 32-bit value must be in network byte order
163+ */
164+ bool operator ==(const uint32_t raw_addr) const noexcept
165+ { return whole == raw_addr; }
91166
92- bool operator <(const Addr rhs) const noexcept
93- { return (*this < rhs.whole ); }
167+ /* *
168+ * Operator to check for inequality
169+ *
170+ * @param other
171+ * The IPv4 address object to check for inequality
172+ *
173+ * @return true if this object is not equal to other, false otherwise
174+ */
175+ bool operator !=(const Addr other) const noexcept
176+ { return not (*this == other); }
94177
95- bool operator <(const uint32_t rhs) const noexcept
96- { return ntohl (whole) < ntohl (rhs); }
178+ /* *
179+ * Operator to check for inequality
180+ *
181+ * @param raw_addr
182+ * The 32-bit value to check for inequality
183+ *
184+ * @return true if this object is equal to not raw_addr, false otherwise
185+ *
186+ * @note The 32-bit value must be in network byte order
187+ */
188+ bool operator !=(const uint32_t raw_addr) const noexcept
189+ { return not (*this == raw_addr); }
97190
98- bool operator >(const Addr rhs) const noexcept
99- { return !(*this < rhs); }
191+ /* *
192+ * Operator to check for less-than relationship
193+ *
194+ * @param other
195+ * The IPv4 address object to check for less-than relationship
196+ *
197+ * @return true if this object is less-than other, false otherwise
198+ */
199+ bool operator <(const Addr other) const noexcept
200+ { return ntohl (whole) < ntohl (other.whole ); }
100201
101- bool operator >(const uint32_t rhs) const noexcept
102- { return !(*this < rhs); }
202+ /* *
203+ * Operator to check for less-than relationship
204+ *
205+ * @param raw_addr
206+ * The 32-bit value to check for less-than relationship
207+ *
208+ * @return true if this object is less-than raw_addr, false otherwise
209+ *
210+ * @note The 32-bit value must be in network byte order
211+ */
212+ bool operator <(const uint32_t raw_addr) const noexcept
213+ { return ntohl (whole) < ntohl (raw_addr); }
103214
104- bool operator !=(const Addr rhs) const noexcept
105- { return !(*this == rhs); }
215+ /* *
216+ * Operator to check for greater-than relationship
217+ *
218+ * @param other
219+ * The IPv4 address object to check for greater-than relationship
220+ *
221+ * @return true if this object is greater-than other, false otherwise
222+ */
223+ bool operator >(const Addr other) const noexcept
224+ { return not (*this < other); }
106225
107- bool operator !=(const uint32_t rhs) const noexcept
108- { return !(*this == rhs); }
226+ /* *
227+ * Operator to check for greater-than relationship
228+ *
229+ * @param raw_addr
230+ * The 32-bit value to check for greater-than relationship
231+ *
232+ * @return true if this object is greater-than raw_addr, false otherwise
233+ *
234+ * @note The 32-bit value must be in network byte order
235+ */
236+ bool operator >(const uint32_t raw_addr) const noexcept
237+ { return not (*this < raw_addr); }
109238
110- Addr operator & (const Addr rhs) const noexcept
111- { return Addr (whole & rhs.whole ); }
239+ /* *
240+ * Operator to perform a bitwise-and operation on the given
241+ * IPv4 addresses
242+ *
243+ * @param other
244+ * The IPv4 address object to perform the bitwise-and operation
245+ *
246+ * @return An IPv4 address object containing the result of the
247+ * operation
248+ */
249+ Addr operator &(const Addr other) const noexcept
250+ { return Addr{whole & other.whole }; }
112251
113- Addr operator | (const Addr rhs) const noexcept
114- { return Addr (whole | rhs.whole ); }
252+ /* *
253+ * Operator to perform a bitwise-or operation on the given
254+ * IPv4 addresses
255+ *
256+ * @param other
257+ * The IPv4 address object to perform the bitwise-or operation
258+ *
259+ * @return An IPv4 address object containing the result of the
260+ * operation
261+ */
262+ Addr operator |(const Addr other) const noexcept
263+ { return Addr{whole | other.whole }; }
115264
116- Addr operator ~ () const noexcept
117- { return Addr (~whole); }
265+ /* *
266+ * Operator to perform a bitwise-not operation on the IPv4
267+ * address
268+ *
269+ * @return An IPv4 address object containing the result of the
270+ * operation
271+ */
272+ Addr operator ~() const noexcept
273+ { return Addr{~whole}; }
118274
119- uint8_t part (uint8_t i) const noexcept {
120- Expects (i < 4 );
275+ /* *
276+ * Get a part from the IPv4 address
277+ *
278+ * @param n
279+ * The part number
280+ *
281+ * @return A part from the IPv4 address
282+ */
283+ uint8_t part (const uint8_t n) const {
284+ Expects (n < 4 );
121285
122- union addr {
123- uint8_t parts[4 ];
286+ const union addr_t {
124287 uint32_t whole;
125- };
288+ uint8_t parts[4 ];
289+ } cubicles {this ->whole };
126290
127- return ((addr&) whole) .parts [3 - i ];
291+ return cubicles .parts [3 - n ];
128292 }
129293
130- /* * x.x.x.x string representation */
294+ /* *
295+ * Get a string representation of the IPv4 address
296+ *
297+ * @return A string representation of the IPv4 address
298+ */
131299 std::string str () const {
132300 char ipv4_addr[16 ];
133- snprintf (ipv4_addr, sizeof (ipv4_addr),
134- " %1i.%1i.%1i.%1i" ,
301+
302+ snprintf (ipv4_addr, sizeof (ipv4_addr), " %1i.%1i.%1i.%1i" ,
135303 (whole >> 0 ) & 0xFF ,
136304 (whole >> 8 ) & 0xFF ,
137305 (whole >> 16 ) & 0xFF ,
138306 (whole >> 24 ) & 0xFF );
307+
139308 return ipv4_addr;
140309 }
141310
311+ /* *
312+ * Get a string representation of this type
313+ *
314+ * @return A string representation of this type
315+ */
142316 std::string to_string () const
143317 { return str (); }
144318
319+ /* Data member */
145320 uint32_t whole;
321+ } __attribute__((packed)); // < struct Addr
146322
147- } __attribute__((packed)); // < Addr
148-
149- } // < namespace ip4
150- } // < namespace net
151-
323+ } // < namespace ip4
324+ } // < namespace net
152325
153- // Allow IP4 address to be used as key in e.g. std::unordered_map
154- namespace std
155- {
156- template <> struct hash <net::ip4::Addr>
157- {
158- using argument_type = net::ip4::Addr;
159- using result_type = uint32_t ;
160- result_type operator ()(argument_type const & addr) const
161- {
162- return std::hash<result_type>{}(addr.whole );
326+ // Allow an IPv4 address to be used as key in e.g. std::unordered_map
327+ namespace std {
328+ template <>
329+ struct hash <net::ip4::Addr> {
330+ size_t operator ()(const net::ip4::Addr& addr) const {
331+ return std::hash<uint32_t >{}(addr.whole );
163332 }
164333 };
165- }
334+ } // < namespace std
166335
167- #endif // < NET_IP4_ADDR_HPP
336+ #endif // < NET_IP4_ADDR_HPP
0 commit comments