forked from Telodendria/Telodendria
[ADD/WIP] Start adding a basic IPv6 parser.
It's only missing verification and a little cleanup
This commit is contained in:
parent
b71b90e7b0
commit
2a61df37ad
1 changed files with 85 additions and 3 deletions
88
src/Parser.c
88
src/Parser.c
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue