Skip to content

Commit 46dc223

Browse files
committed
Merge branch 'dev' of github.com:hioa-cs/IncludeOS into dev
2 parents 4d47dfe + 8cdf933 commit 46dc223

19 files changed

Lines changed: 1338 additions & 646 deletions

api/net/ip4/addr.hpp

Lines changed: 243 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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");
@@ -15,46 +15,96 @@
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

2628
namespace net {
2729
namespace 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+
*/
3443
struct 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

Comments
 (0)