diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-01-26 08:55:35 +0100 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2014-01-26 08:55:35 +0100 |
commit | b78d55b69ed9d9c88d12f0159e78973ad0d70b49 (patch) | |
tree | a7ee07d0582830fe05f2a467966350f557da1c4e /src/lex.c | |
parent | e975ea01bbe71533d3eda883bf054a1487258ef8 (diff) | |
download | fastd-b78d55b69ed9d9c88d12f0159e78973ad0d70b49.tar fastd-b78d55b69ed9d9c88d12f0159e78973ad0d70b49.zip |
Allow scoped IPv6 addresses for remotes using the usual notation
Diffstat (limited to 'src/lex.c')
-rw-r--r-- | src/lex.c | 40 |
1 files changed, 37 insertions, 3 deletions
@@ -279,20 +279,54 @@ static int parse_ipv6_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex break; } - bool ok = (current(lex) == ']'); + char cur = current(lex); + + bool ifname = (cur == '%') ? lex->start + lex->tok_len + 1 : 0; + + bool ok = ifname || (cur == ']'); if (ok) { lex->buffer[lex->start + lex->tok_len] = 0; - ok = inet_pton(AF_INET6, lex->buffer+lex->start+1, &yylval->addr6); + ok = inet_pton(AF_INET6, lex->buffer+lex->start+1, ifname ? &yylval->addr6_scoped.addr : &yylval->addr6); } if (!ok) return syntax_error(yylval, lex); + if (ifname) { + consume(lex, false); + + size_t pos = 0; + + while (true) { + if (!next(yylloc, lex, true)) + return syntax_error(yylval, lex); + + cur = current(lex); + + if (cur == ']') + break; + + if (cur == '\\') { + if (!next(yylloc, lex, true)) + return syntax_error(yylval, lex); + + cur = current(lex); + } + + if (pos == sizeof(yylval->addr6_scoped.ifname)-1) + return syntax_error(yylval, lex); + + yylval->addr6_scoped.ifname[pos++] = cur; + } + + yylval->addr6_scoped.ifname[pos] = 0; + } + next(yylloc, lex, true); consume(lex, true); - return TOK_ADDR6; + return ifname ? TOK_ADDR6_SCOPED : TOK_ADDR6; } static int parse_ipv4_address(YYSTYPE *yylval, YYLTYPE *yylloc, fastd_lex_t *lex) { |