IPv4: fix buggy ascii_to implementations

Ref #2193
This commit is contained in:
Martin Stein
2016-12-22 03:08:12 +01:00
committed by Norman Feske
parent 045a30865a
commit 8d521036fb

View File

@ -241,62 +241,58 @@ namespace Genode {
Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address &result) Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address &result)
{ {
using namespace Net; Net::Ipv4_address buf;
size_t number_idx = 0;
size_t read_len = 0;
while (1) {
struct Scanner_policy_number /* read the current number, fail if there's no number */
{ size_t number_len = ascii_to_unsigned(s, buf.addr[number_idx], 10);
static bool identifier_char(char c, unsigned i ) { if (!number_len) {
return Genode::is_digit(c) && c !='.'; } return 0; }
};
typedef ::Genode::Token<Scanner_policy_number> Token; /* update read length and number index */
read_len += number_len;
number_idx++;
Ipv4_address ip_addr; /* if we have all numbers, fill result and return read length */
Token t(s); if (number_idx == sizeof(buf.addr) / sizeof(buf.addr[0])) {
char tmpstr[4]; result = buf;
int cnt = 0; return read_len;
unsigned char ipb[4] = {0};
size_t size = 0;
while(t) {
if (t.type() == Token::WHITESPACE || t[0] == '.') {
t = t.next();
size++;
continue;
} }
t.string(tmpstr, sizeof(tmpstr)); /* as it was not the last number, check for the following dot */
s += number_len;
unsigned long tmpc = 0; if (*s != '.') {
size += Genode::ascii_to(tmpstr, tmpc); return 0; }
ipb[cnt] = tmpc & 0xFF; read_len++;
t = t.next(); s++;
if (cnt == 4)
break;
cnt++;
} }
if (cnt == 4) {
result.addr[0] = ipb[0];
result.addr[1] = ipb[1];
result.addr[2] = ipb[2];
result.addr[3] = ipb[3];
return size;
}
return 0;
} }
Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address_prefix &result) Genode::size_t Genode::ascii_to(char const *s, Net::Ipv4_address_prefix &result)
{ {
size_t size = ascii_to(s, result.address); /* read the leading IPv4 address, fail if there's no address */
if (!size || s[size] != '/') { return 0; } Net::Ipv4_address_prefix buf;
char const * prefix = &s[size + 1]; size_t read_len = ascii_to(s, buf.address);
size_t const prefix_size = ascii_to_unsigned(prefix, result.prefix, 10); if (!read_len) {
if (!prefix_size) { return 0; } return 0; }
size += prefix_size + 1;
return size; /* check for the following slash */
s += read_len;
if (*s != '/') {
return 0; }
read_len++;
s++;
/* read the prefix, fail if there's no prefix */
size_t prefix_len = ascii_to_unsigned(s, buf.prefix, 10);
if (!prefix_len) {
return 0; }
/* fill result and return read length */
result = buf;
return read_len + prefix_len;
} }
#endif /* _IPV4_H_ */ #endif /* _IPV4_H_ */