Skip to content

Commit 064d768

Browse files
authored
Merge pull request #1440 from fwsGonzo/dev
net: Custom IP4 string constructor, some test fixes
2 parents 4117bc1 + d52874a commit 064d768

5 files changed

Lines changed: 41 additions & 32 deletions

File tree

api/net/ip4/addr.hpp

Lines changed: 31 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@
1919
#ifndef NET_IP4_ADDR_HPP
2020
#define NET_IP4_ADDR_HPP
2121

22-
#include <regex>
23-
#include <string>
24-
2522
#include <common>
2623
#include <net/util.hpp>
24+
#include <cstdlib>
25+
#include <string>
2726

2827
namespace net {
2928
namespace ip4 {
@@ -98,34 +97,38 @@ struct Addr {
9897
* IIf the {std::string} object doesn't representing a valid IPv4
9998
* address
10099
*/
101-
template<typename = void>
102-
Addr(const std::string& ipv4_addr)
100+
Addr(const std::string& str)
103101
{
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-
108-
const static std::regex ipv4_address_pattern
102+
int value[4] = {0};
103+
int index = 0;
104+
bool length_error = true;
105+
const char* ptr = str.c_str();
106+
while (*ptr)
109107
{
110-
111-
#define OCTET_PATTERN "(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)"
112-
"^\\s*" OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\." OCTET_PATTERN "\\s*$"
113-
#undef OCTET_PATTERN
114-
115-
};
116-
117-
std::smatch ipv4_parts;
118-
119-
if (not std::regex_match(ipv4_addr, ipv4_parts, ipv4_address_pattern)) {
120-
throw Invalid_address{ipv4_addr + " is not a valid IP"};
108+
if (std::isdigit((int) *ptr))
109+
{
110+
value[index] *= 10;
111+
value[index] += *ptr - '0';
112+
if (value[index] & 0xFFFFFF00) {
113+
throw Invalid_address("Out-of-range byte values in " + str);
114+
}
115+
length_error = false;
116+
} else {
117+
if (*ptr == '.') {
118+
if (++index > 3)
119+
throw Invalid_address("Too many dots in " + str);
120+
length_error = true;
121+
}
122+
else {
123+
throw Invalid_address("Unexpected characters in " + str);
124+
}
125+
}
126+
ptr++;
121127
}
122-
123-
const auto p1 = static_cast<uint8_t>(std::stoi(ipv4_parts[1]));
124-
const auto p2 = static_cast<uint8_t>(std::stoi(ipv4_parts[2]));
125-
const auto p3 = static_cast<uint8_t>(std::stoi(ipv4_parts[3]));
126-
const auto p4 = static_cast<uint8_t>(std::stoi(ipv4_parts[4]));
127-
128-
whole = p1 | (p2 << 8) | (p3 << 16) | (p4 << 24);
128+
if (length_error) {
129+
throw Invalid_address("Missing byte value at end of " + str);
130+
}
131+
this->whole = value[0] | (value[1] << 8) | (value[2] << 16) | (value[3] << 24);
129132
}
130133

131134
/**

api/net/tcp/packet.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Socket source() const
317317
os << "[ S:" << source().to_string() << " D:" << destination().to_string()
318318
<< " SEQ:" << seq() << " ACK:" << ack()
319319
<< " HEAD-LEN:" << (int)tcp_header_length() << " OPT-LEN:" << (int)tcp_options_length() << " DATA-LEN:" << tcp_data_length()
320-
<< " WIN:" << win() << " FLAGS:" << std::bitset<8>{tcp_header().offset_flags.flags} << " ]";
320+
<< " WIN:" << win() << " FLAGS:" << tcp_header().offset_flags.flags << " ]";
321321
return os.str();
322322
}
323323

src/posix/arpa/inet.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <arpa/inet.h>
1919
#include <net/ip4/addr.hpp>
2020
#include <common>
21+
#include <errno.h>
2122

2223
/**
2324
* @note: shortcut, not sufficent.

test/net/unit/ip4_addr.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,13 @@ CASE("Create IP4 addresses from strings")
4949
EXPECT( valid_addr.to_string() == valid_addr_str );
5050

5151
std::string extra_whitespace_addr_str {"\r 10.0.0.42 \n\r"};
52-
Addr ipv4_address {extra_whitespace_addr_str};
53-
EXPECT(ipv4_address.str() == "10.0.0.42");
52+
EXPECT_THROWS(Addr{extra_whitespace_addr_str});
53+
EXPECT(Addr{"10"} == Addr(10,0,0,0));
54+
EXPECT_THROWS(Addr{"10."});
55+
EXPECT(Addr{"10.0"} == Addr(10,0,0,0));
56+
EXPECT_THROWS(Addr{"10.0."});
57+
EXPECT(Addr{"10.0.0"} == Addr(10,0,0,0));
58+
EXPECT_THROWS(Addr{"10.0.0."});
5459

5560
// Check some special cases / previously failed cases
5661
std::vector<std::string> ips {

test/posix/unit/inet_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,5 +87,5 @@ CASE("IPv4 address manipulation - pointer to addr")
8787

8888
// Unsupported IP4 format
8989
res = inet_pton(AF_INET, "255.255.0", &addr);
90-
EXPECT(res == 0);
90+
EXPECT(res == 1);
9191
}

0 commit comments

Comments
 (0)