#ifndef IP4_H
#define IP4_H
nonnull_all
static really_inline int32_t scan_ip4(const char *text, uint8_t *wire)
{
const char *start = text;
uint32_t round = 0;
for (;;) {
uint8_t digits[3], count;
uint32_t octet;
digits[0] = (uint8_t)text[0] - '0';
digits[1] = (uint8_t)text[1] - '0';
digits[2] = (uint8_t)text[2] - '0';
if (digits[0] > 9)
return 0;
else if (digits[1] > 9)
(void)(count = 1), octet = digits[0];
else if (digits[2] > 9)
(void)(count = 2), octet = digits[0] * 10 + digits[1];
else
(void)(count = 3), octet = digits[0] * 100 + digits[1] * 10 + digits[2];
if (octet > 255 || (count > 1 && !digits[0]))
return 0;
text += count;
wire[round++] = (uint8_t)octet;
if (text[0] != '.' || round == 4)
break;
text += 1;
}
if (round != 4)
return 0;
return (int32_t)(text - start);
}
nonnull_all
static really_inline int32_t parse_ip4(
parser_t *parser,
const type_info_t *type,
const rdata_info_t *item,
rdata_t *rdata,
const token_t *token)
{
if ((size_t)scan_ip4(token->data, rdata->octets) != token->length)
SYNTAX_ERROR(parser, "Invalid %s in %s", NAME(item), NAME(type));
rdata->octets += 4;
return 0;
}
#endif