[ADD/WIP] Start adding a basic IPv6 parser.

It's only missing verification and a little cleanup
This commit is contained in:
lda 2023-12-08 20:07:19 +01:00
parent b71b90e7b0
commit 2a61df37ad

View file

@ -126,11 +126,93 @@ ParseIPv4(char **str, char **out)
return 1; return 1;
} }
static int static int
IsIPv6Char(char c)
{
return isxdigit(c) || c == ':' || c == '.';
}
static int
ParseIPv6(char **str, char **out) ParseIPv6(char **str, char **out)
{ {
/* TODO */ char *start;
(void) str; size_t length;
(void) out; char c;
int filled = 0;
int digit = 0;
int digits = 0;
start = *str;
length = 0;
if (Iterate(str) != '[')
{
goto fail;
}
while ((c = Iterate(str)) && IsIPv6Char(c))
{
char *ipv4;
if (isxdigit(c))
{
digit++;
length++;
continue;
}
if (c == ':')
{
if (**str == ':')
{
digit = 0;
if (!filled)
{
filled = 1;
length++;
c = Iterate(str); /* Skip over the character */
continue;
}
/* RFC3513 says the following:
* > 'The "::" can only appear once in an address.' */
*str = start;
return 0;
}
if (digit < 1 || digit > 4)
{
goto fail;
}
/* We do not have to check whenever the digit here is valid,
* because it has to be .*/
digit = 0;
digits++;
length++;
continue;
}
/* The only remaining character being '.', we are probably dealing
* with an IPv4 literal. */
*str -= digit + 1;
length -= digit + 1;
if (ParseIPv4(str, &ipv4))
{
length += strlen(ipv4);
Free(ipv4);
c = Iterate(str);
goto end;
}
}
end:
--(*str);
if (Iterate(str) != ']')
{
goto fail;
}
length = (size_t) (*str - start);
*out = Malloc(length + 1);
memcpy(*out, start, length);
return 1;
fail:
*str = start;
return 0; return 0;
} }
static int static int