|
Packit |
c5a612 |
/*
|
|
Packit |
c5a612 |
* Copyright (c) 2007-2008 Patrick McHardy <kaber@trash.net>
|
|
Packit |
c5a612 |
*
|
|
Packit |
c5a612 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
c5a612 |
* it under the terms of the GNU General Public License version 2 as
|
|
Packit |
c5a612 |
* published by the Free Software Foundation.
|
|
Packit |
c5a612 |
*
|
|
Packit |
c5a612 |
* Development of this code funded by Astaro AG (http://www.astaro.com/)
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
%{
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
#include <limits.h>
|
|
Packit |
c5a612 |
#include <glob.h>
|
|
Packit |
c5a612 |
#include <netinet/in.h>
|
|
Packit |
c5a612 |
#include <arpa/inet.h>
|
|
Packit |
c5a612 |
#include <linux/types.h>
|
|
Packit |
c5a612 |
#include <linux/netfilter.h>
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
#include <nftables.h>
|
|
Packit |
c5a612 |
#include <erec.h>
|
|
Packit |
c5a612 |
#include <rule.h>
|
|
Packit |
c5a612 |
#include <parser.h>
|
|
Packit |
c5a612 |
#include "parser_bison.h"
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
#define YY_NO_INPUT
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/*
|
|
Packit |
c5a612 |
* Work around flex behaviour when reaching the end of buffer: normally, flex
|
|
Packit |
c5a612 |
* regexes are greedy, when reaching the end of buffer however it tries to
|
|
Packit |
c5a612 |
* match whatever is left in the buffer and only backs up in case it doesn't
|
|
Packit |
c5a612 |
* match *any* pattern. Since we accept unquoted strings, this means any partial
|
|
Packit |
c5a612 |
* token will be recognized as string.
|
|
Packit |
c5a612 |
*
|
|
Packit |
c5a612 |
* Make sure to only pass input to flex linewise to avoid this.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
#define YY_INPUT(buf,result,max_size) \
|
|
Packit |
c5a612 |
{ \
|
|
Packit |
c5a612 |
result = 0; \
|
|
Packit |
c5a612 |
errno = 0; \
|
|
Packit |
c5a612 |
\
|
|
Packit |
c5a612 |
while (result < max_size) { \
|
|
Packit |
c5a612 |
int chr = fgetc(yyin); \
|
|
Packit |
c5a612 |
\
|
|
Packit |
c5a612 |
if (chr != EOF) { \
|
|
Packit |
c5a612 |
buf[result++] = chr; \
|
|
Packit |
c5a612 |
if (chr == '\n' || chr == ' ') \
|
|
Packit |
c5a612 |
break; \
|
|
Packit |
c5a612 |
continue; \
|
|
Packit |
c5a612 |
} \
|
|
Packit |
c5a612 |
\
|
|
Packit |
c5a612 |
if (ferror(yyin)) { \
|
|
Packit |
c5a612 |
if (errno != EINTR) { \
|
|
Packit |
c5a612 |
YY_FATAL_ERROR("input in flex scanner failed"); \
|
|
Packit |
c5a612 |
break; \
|
|
Packit |
c5a612 |
} \
|
|
Packit |
c5a612 |
errno = 0; \
|
|
Packit |
c5a612 |
clearerr(yyin); \
|
|
Packit |
c5a612 |
} \
|
|
Packit |
c5a612 |
break; \
|
|
Packit |
c5a612 |
} \
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void scanner_pop_buffer(yyscan_t scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void init_pos(struct input_descriptor *indesc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
indesc->lineno = 1;
|
|
Packit |
c5a612 |
indesc->column = 1;
|
|
Packit |
c5a612 |
indesc->token_offset = 0;
|
|
Packit |
c5a612 |
indesc->line_offset = 0;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void update_pos(struct parser_state *state, struct location *loc,
|
|
Packit |
c5a612 |
int len)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
loc->indesc = state->indesc;
|
|
Packit |
c5a612 |
loc->first_line = state->indesc->lineno;
|
|
Packit |
c5a612 |
loc->last_line = state->indesc->lineno;
|
|
Packit |
c5a612 |
loc->first_column = state->indesc->column;
|
|
Packit |
c5a612 |
loc->last_column = state->indesc->column + len - 1;
|
|
Packit |
c5a612 |
state->indesc->column += len;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void update_offset(struct parser_state *state, struct location *loc,
|
|
Packit |
c5a612 |
unsigned int len)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
state->indesc->token_offset += len;
|
|
Packit |
c5a612 |
loc->token_offset = state->indesc->token_offset;
|
|
Packit |
c5a612 |
loc->line_offset = state->indesc->line_offset;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void reset_pos(struct parser_state *state, struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
state->indesc->line_offset = state->indesc->token_offset;
|
|
Packit |
c5a612 |
state->indesc->lineno += 1;
|
|
Packit |
c5a612 |
state->indesc->column = 1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
#define YY_USER_ACTION { \
|
|
Packit |
c5a612 |
update_pos(yyget_extra(yyscanner), yylloc, yyleng); \
|
|
Packit |
c5a612 |
update_offset(yyget_extra(yyscanner), yylloc, yyleng); \
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* avoid warnings with -Wmissing-prototypes */
|
|
Packit |
c5a612 |
extern int yyget_column(yyscan_t);
|
|
Packit |
c5a612 |
extern void yyset_column(int, yyscan_t);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
%}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
space [ ]
|
|
Packit |
c5a612 |
tab \t
|
|
Packit |
c5a612 |
newline \n
|
|
Packit |
c5a612 |
digit [0-9]
|
|
Packit |
c5a612 |
hexdigit [0-9a-fA-F]
|
|
Packit |
c5a612 |
decstring {digit}+
|
|
Packit |
c5a612 |
hexstring 0[xX]{hexdigit}+
|
|
Packit |
c5a612 |
numberstring ({decstring}|{hexstring})
|
|
Packit |
c5a612 |
letter [a-zA-Z]
|
|
Packit |
c5a612 |
string ({letter}|[_.])({letter}|{digit}|[/\-_\.])*
|
|
Packit |
c5a612 |
quotedstring \"[^"]*\"
|
|
Packit Service |
b7c5bc |
asteriskstring ({string}\*|{string}\\\*|\\\*|{string}\\\*{string})
|
|
Packit |
c5a612 |
comment #.*$
|
|
Packit |
c5a612 |
slash \/
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
timestring ([0-9]+d)?([0-9]+h)?([0-9]+m)?([0-9]+s)?([0-9]+ms)?
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
hex4 ([[:xdigit:]]{1,4})
|
|
Packit |
c5a612 |
v680 (({hex4}:){7}{hex4})
|
|
Packit |
c5a612 |
v670 ((:)((:{hex4}){7}))
|
|
Packit |
c5a612 |
v671 ((({hex4}:){1})((:{hex4}){6}))
|
|
Packit |
c5a612 |
v672 ((({hex4}:){2})((:{hex4}){5}))
|
|
Packit |
c5a612 |
v673 ((({hex4}:){3})((:{hex4}){4}))
|
|
Packit |
c5a612 |
v674 ((({hex4}:){4})((:{hex4}){3}))
|
|
Packit |
c5a612 |
v675 ((({hex4}:){5})((:{hex4}){2}))
|
|
Packit |
c5a612 |
v676 ((({hex4}:){6})(:{hex4}{1}))
|
|
Packit |
c5a612 |
v677 ((({hex4}:){7})(:))
|
|
Packit |
c5a612 |
v67 ({v670}|{v671}|{v672}|{v673}|{v674}|{v675}|{v676}|{v677})
|
|
Packit |
c5a612 |
v660 ((:)((:{hex4}){6}))
|
|
Packit |
c5a612 |
v661 ((({hex4}:){1})((:{hex4}){5}))
|
|
Packit |
c5a612 |
v662 ((({hex4}:){2})((:{hex4}){4}))
|
|
Packit |
c5a612 |
v663 ((({hex4}:){3})((:{hex4}){3}))
|
|
Packit |
c5a612 |
v664 ((({hex4}:){4})((:{hex4}){2}))
|
|
Packit |
c5a612 |
v665 ((({hex4}:){5})((:{hex4}){1}))
|
|
Packit |
c5a612 |
v666 ((({hex4}:){6})(:))
|
|
Packit |
c5a612 |
v66 ({v660}|{v661}|{v662}|{v663}|{v664}|{v665}|{v666})
|
|
Packit |
c5a612 |
v650 ((:)((:{hex4}){5}))
|
|
Packit |
c5a612 |
v651 ((({hex4}:){1})((:{hex4}){4}))
|
|
Packit |
c5a612 |
v652 ((({hex4}:){2})((:{hex4}){3}))
|
|
Packit |
c5a612 |
v653 ((({hex4}:){3})((:{hex4}){2}))
|
|
Packit |
c5a612 |
v654 ((({hex4}:){4})(:{hex4}{1}))
|
|
Packit |
c5a612 |
v655 ((({hex4}:){5})(:))
|
|
Packit |
c5a612 |
v65 ({v650}|{v651}|{v652}|{v653}|{v654}|{v655})
|
|
Packit |
c5a612 |
v640 ((:)((:{hex4}){4}))
|
|
Packit |
c5a612 |
v641 ((({hex4}:){1})((:{hex4}){3}))
|
|
Packit |
c5a612 |
v642 ((({hex4}:){2})((:{hex4}){2}))
|
|
Packit |
c5a612 |
v643 ((({hex4}:){3})((:{hex4}){1}))
|
|
Packit |
c5a612 |
v644 ((({hex4}:){4})(:))
|
|
Packit |
c5a612 |
v64 ({v640}|{v641}|{v642}|{v643}|{v644})
|
|
Packit |
c5a612 |
v630 ((:)((:{hex4}){3}))
|
|
Packit |
c5a612 |
v631 ((({hex4}:){1})((:{hex4}){2}))
|
|
Packit |
c5a612 |
v632 ((({hex4}:){2})((:{hex4}){1}))
|
|
Packit |
c5a612 |
v633 ((({hex4}:){3})(:))
|
|
Packit |
c5a612 |
v63 ({v630}|{v631}|{v632}|{v633})
|
|
Packit |
c5a612 |
v620 ((:)((:{hex4}){2}))
|
|
Packit |
c5a612 |
v620_rfc4291 ((:)(:{ip4addr}))
|
|
Packit |
c5a612 |
v621 ((({hex4}:){1})((:{hex4}){1}))
|
|
Packit |
c5a612 |
v622 ((({hex4}:){2})(:))
|
|
Packit |
c5a612 |
v62_rfc4291 ((:)(:[fF]{4})(:{ip4addr}))
|
|
Packit |
c5a612 |
v62 ({v620}|{v621}|{v622}|{v62_rfc4291}|{v620_rfc4291})
|
|
Packit |
c5a612 |
v610 ((:)(:{hex4}{1}))
|
|
Packit |
c5a612 |
v611 ((({hex4}:){1})(:))
|
|
Packit |
c5a612 |
v61 ({v610}|{v611})
|
|
Packit |
c5a612 |
v60 (::)
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
macaddr (([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2})
|
|
Packit |
c5a612 |
ip4addr (([[:digit:]]{1,3}"."){3}([[:digit:]]{1,3}))
|
|
Packit |
c5a612 |
ip6addr ({v680}|{v67}|{v66}|{v65}|{v64}|{v63}|{v62}|{v61}|{v60})
|
|
Packit |
c5a612 |
ip6addr_rfc2732 (\[{ip6addr}\])
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
classid ({hexdigit}{1,4}:{hexdigit}{1,4})
|
|
Packit |
c5a612 |
addrstring ({macaddr}|{ip4addr}|{ip6addr})
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
%option prefix="nft_"
|
|
Packit |
c5a612 |
%option outfile="lex.yy.c"
|
|
Packit |
c5a612 |
%option reentrant
|
|
Packit |
c5a612 |
%option noyywrap
|
|
Packit |
c5a612 |
%option nounput
|
|
Packit |
c5a612 |
%option bison-bridge
|
|
Packit |
c5a612 |
%option bison-locations
|
|
Packit |
c5a612 |
%option debug
|
|
Packit |
c5a612 |
%option yylineno
|
|
Packit |
c5a612 |
%option nodefault
|
|
Packit |
c5a612 |
%option warn
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
%%
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"==" { return EQ; }
|
|
Packit |
c5a612 |
"eq" { return EQ; }
|
|
Packit |
c5a612 |
"!=" { return NEQ; }
|
|
Packit |
c5a612 |
"ne" { return NEQ; }
|
|
Packit |
c5a612 |
"<=" { return LTE; }
|
|
Packit |
c5a612 |
"le" { return LTE; }
|
|
Packit |
c5a612 |
"<" { return LT; }
|
|
Packit |
c5a612 |
"lt" { return LT; }
|
|
Packit |
c5a612 |
">=" { return GTE; }
|
|
Packit |
c5a612 |
"ge" { return GTE; }
|
|
Packit |
c5a612 |
">" { return GT; }
|
|
Packit |
c5a612 |
"gt" { return GT; }
|
|
Packit |
c5a612 |
"," { return COMMA; }
|
|
Packit |
c5a612 |
"." { return DOT; }
|
|
Packit |
c5a612 |
":" { return COLON; }
|
|
Packit |
c5a612 |
";" { return SEMICOLON; }
|
|
Packit |
c5a612 |
"{" { return '{'; }
|
|
Packit |
c5a612 |
"}" { return '}'; }
|
|
Packit |
c5a612 |
"[" { return '['; }
|
|
Packit |
c5a612 |
"]" { return ']'; }
|
|
Packit |
c5a612 |
"(" { return '('; }
|
|
Packit |
c5a612 |
")" { return ')'; }
|
|
Packit |
c5a612 |
"<<" { return LSHIFT; }
|
|
Packit |
c5a612 |
"lshift" { return LSHIFT; }
|
|
Packit |
c5a612 |
">>" { return RSHIFT; }
|
|
Packit |
c5a612 |
"rshift" { return RSHIFT; }
|
|
Packit |
c5a612 |
"^" { return CARET; }
|
|
Packit |
c5a612 |
"xor" { return CARET; }
|
|
Packit |
c5a612 |
"&" { return AMPERSAND; }
|
|
Packit |
c5a612 |
"and" { return AMPERSAND; }
|
|
Packit |
c5a612 |
"|" { return '|'; }
|
|
Packit |
c5a612 |
"or" { return '|'; }
|
|
Packit |
c5a612 |
"!" { return NOT; }
|
|
Packit |
c5a612 |
"not" { return NOT; }
|
|
Packit |
c5a612 |
"/" { return SLASH; }
|
|
Packit |
c5a612 |
"-" { return DASH; }
|
|
Packit |
c5a612 |
"*" { return ASTERISK; }
|
|
Packit |
c5a612 |
"@" { return AT; }
|
|
Packit |
c5a612 |
"$" { return '$'; }
|
|
Packit |
c5a612 |
"=" { return '='; }
|
|
Packit |
c5a612 |
"vmap" { return VMAP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"+" { return PLUS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"include" { return INCLUDE; }
|
|
Packit |
c5a612 |
"define" { return DEFINE; }
|
|
Packit |
c5a612 |
"redefine" { return REDEFINE; }
|
|
Packit |
c5a612 |
"undefine" { return UNDEFINE; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"describe" { return DESCRIBE; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"hook" { return HOOK; }
|
|
Packit |
c5a612 |
"device" { return DEVICE; }
|
|
Packit |
c5a612 |
"devices" { return DEVICES; }
|
|
Packit |
c5a612 |
"table" { return TABLE; }
|
|
Packit |
c5a612 |
"tables" { return TABLES; }
|
|
Packit |
c5a612 |
"chain" { return CHAIN; }
|
|
Packit |
c5a612 |
"chains" { return CHAINS; }
|
|
Packit |
c5a612 |
"rule" { return RULE; }
|
|
Packit |
c5a612 |
"rules" { return RULES; }
|
|
Packit |
c5a612 |
"sets" { return SETS; }
|
|
Packit |
c5a612 |
"set" { return SET; }
|
|
Packit |
c5a612 |
"element" { return ELEMENT; }
|
|
Packit |
c5a612 |
"map" { return MAP; }
|
|
Packit |
c5a612 |
"maps" { return MAPS; }
|
|
Packit |
c5a612 |
"flowtable" { return FLOWTABLE; }
|
|
Packit |
c5a612 |
"handle" { return HANDLE; }
|
|
Packit |
c5a612 |
"ruleset" { return RULESET; }
|
|
Packit |
c5a612 |
"trace" { return TRACE; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"socket" { return SOCKET; }
|
|
Packit |
c5a612 |
"transparent" { return TRANSPARENT;}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"tproxy" { return TPROXY; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"accept" { return ACCEPT; }
|
|
Packit |
c5a612 |
"drop" { return DROP; }
|
|
Packit |
c5a612 |
"continue" { return CONTINUE; }
|
|
Packit |
c5a612 |
"jump" { return JUMP; }
|
|
Packit |
c5a612 |
"goto" { return GOTO; }
|
|
Packit |
c5a612 |
"return" { return RETURN; }
|
|
Packit |
c5a612 |
"to" { return TO; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"inet" { return INET; }
|
|
Packit |
c5a612 |
"netdev" { return NETDEV; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"add" { return ADD; }
|
|
Packit |
c5a612 |
"replace" { return REPLACE; }
|
|
Packit |
c5a612 |
"update" { return UPDATE; }
|
|
Packit |
c5a612 |
"create" { return CREATE; }
|
|
Packit |
c5a612 |
"insert" { return INSERT; }
|
|
Packit |
c5a612 |
"delete" { return DELETE; }
|
|
Packit |
c5a612 |
"get" { return GET; }
|
|
Packit |
c5a612 |
"list" { return LIST; }
|
|
Packit |
c5a612 |
"reset" { return RESET; }
|
|
Packit |
c5a612 |
"flush" { return FLUSH; }
|
|
Packit |
c5a612 |
"rename" { return RENAME; }
|
|
Packit |
c5a612 |
"import" { return IMPORT; }
|
|
Packit |
c5a612 |
"export" { return EXPORT; }
|
|
Packit |
c5a612 |
"monitor" { return MONITOR; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"position" { return POSITION; }
|
|
Packit |
c5a612 |
"index" { return INDEX; }
|
|
Packit |
c5a612 |
"comment" { return COMMENT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"constant" { return CONSTANT; }
|
|
Packit |
c5a612 |
"interval" { return INTERVAL; }
|
|
Packit |
c5a612 |
"dynamic" { return DYNAMIC; }
|
|
Packit |
c5a612 |
"auto-merge" { return AUTOMERGE; }
|
|
Packit |
c5a612 |
"timeout" { return TIMEOUT; }
|
|
Packit |
c5a612 |
"gc-interval" { return GC_INTERVAL; }
|
|
Packit |
c5a612 |
"elements" { return ELEMENTS; }
|
|
Packit |
c5a612 |
"expires" { return EXPIRES; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"policy" { return POLICY; }
|
|
Packit |
c5a612 |
"size" { return SIZE; }
|
|
Packit |
c5a612 |
"performance" { return PERFORMANCE; }
|
|
Packit |
c5a612 |
"memory" { return MEMORY; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"flow" { return FLOW; }
|
|
Packit |
c5a612 |
"offload" { return OFFLOAD; }
|
|
Packit |
c5a612 |
"meter" { return METER; }
|
|
Packit |
c5a612 |
"meters" { return METERS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"flowtables" { return FLOWTABLES; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"counter" { return COUNTER; }
|
|
Packit |
c5a612 |
"name" { return NAME; }
|
|
Packit |
c5a612 |
"packets" { return PACKETS; }
|
|
Packit |
c5a612 |
"bytes" { return BYTES; }
|
|
Packit |
c5a612 |
"avgpkt" { return AVGPKT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"counters" { return COUNTERS; }
|
|
Packit |
c5a612 |
"quotas" { return QUOTAS; }
|
|
Packit |
c5a612 |
"limits" { return LIMITS; }
|
|
Packit |
c5a612 |
"synproxys" { return SYNPROXYS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"log" { return LOG; }
|
|
Packit |
c5a612 |
"prefix" { return PREFIX; }
|
|
Packit |
c5a612 |
"group" { return GROUP; }
|
|
Packit |
c5a612 |
"snaplen" { return SNAPLEN; }
|
|
Packit |
c5a612 |
"queue-threshold" { return QUEUE_THRESHOLD; }
|
|
Packit |
c5a612 |
"level" { return LEVEL; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"queue" { return QUEUE;}
|
|
Packit |
c5a612 |
"num" { return QUEUENUM;}
|
|
Packit |
c5a612 |
"bypass" { return BYPASS;}
|
|
Packit |
c5a612 |
"fanout" { return FANOUT;}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"limit" { return LIMIT; }
|
|
Packit |
c5a612 |
"rate" { return RATE; }
|
|
Packit |
c5a612 |
"burst" { return BURST; }
|
|
Packit |
c5a612 |
"until" { return UNTIL; }
|
|
Packit |
c5a612 |
"over" { return OVER; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"quota" { return QUOTA; }
|
|
Packit |
c5a612 |
"used" { return USED; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"nanosecond" { return NANOSECOND; }
|
|
Packit |
c5a612 |
"microsecond" { return MICROSECOND; }
|
|
Packit |
c5a612 |
"millisecond" { return MILLISECOND; }
|
|
Packit |
c5a612 |
"second" { return SECOND; }
|
|
Packit |
c5a612 |
"minute" { return MINUTE; }
|
|
Packit |
c5a612 |
"hour" { return HOUR; }
|
|
Packit |
c5a612 |
"day" { return DAY; }
|
|
Packit |
c5a612 |
"week" { return WEEK; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"reject" { return _REJECT; }
|
|
Packit |
c5a612 |
"with" { return WITH; }
|
|
Packit |
c5a612 |
"icmpx" { return ICMPX; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"snat" { return SNAT; }
|
|
Packit |
c5a612 |
"dnat" { return DNAT; }
|
|
Packit |
c5a612 |
"masquerade" { return MASQUERADE; }
|
|
Packit |
c5a612 |
"redirect" { return REDIRECT; }
|
|
Packit |
c5a612 |
"random" { return RANDOM; }
|
|
Packit |
c5a612 |
"fully-random" { return FULLY_RANDOM; }
|
|
Packit |
c5a612 |
"persistent" { return PERSISTENT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ll" { return LL_HDR; }
|
|
Packit |
c5a612 |
"nh" { return NETWORK_HDR; }
|
|
Packit |
c5a612 |
"th" { return TRANSPORT_HDR; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"bridge" { return BRIDGE; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ether" { return ETHER; }
|
|
Packit |
c5a612 |
"saddr" { return SADDR; }
|
|
Packit |
c5a612 |
"daddr" { return DADDR; }
|
|
Packit |
c5a612 |
"type" { return TYPE; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"vlan" { return VLAN; }
|
|
Packit |
c5a612 |
"id" { return ID; }
|
|
Packit |
c5a612 |
"cfi" { return CFI; }
|
|
Packit |
c5a612 |
"pcp" { return PCP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"arp" { return ARP; }
|
|
Packit |
c5a612 |
"htype" { return HTYPE; }
|
|
Packit |
c5a612 |
"ptype" { return PTYPE; }
|
|
Packit |
c5a612 |
"hlen" { return HLEN; }
|
|
Packit |
c5a612 |
"plen" { return PLEN; }
|
|
Packit |
c5a612 |
"operation" { return OPERATION; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ip" { return IP; }
|
|
Packit |
c5a612 |
"version" { return HDRVERSION; }
|
|
Packit |
c5a612 |
"hdrlength" { return HDRLENGTH; }
|
|
Packit |
c5a612 |
"dscp" { return DSCP; }
|
|
Packit |
c5a612 |
"ecn" { return ECN; }
|
|
Packit |
c5a612 |
"length" { return LENGTH; }
|
|
Packit |
c5a612 |
"frag-off" { return FRAG_OFF; }
|
|
Packit |
c5a612 |
"ttl" { return TTL; }
|
|
Packit |
c5a612 |
"protocol" { return PROTOCOL; }
|
|
Packit |
c5a612 |
"checksum" { return CHECKSUM; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"lsrr" { return LSRR; }
|
|
Packit |
c5a612 |
"rr" { return RR; }
|
|
Packit |
c5a612 |
"ssrr" { return SSRR; }
|
|
Packit |
c5a612 |
"ra" { return RA; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"value" { return VALUE; }
|
|
Packit |
c5a612 |
"ptr" { return PTR; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"echo" { return ECHO; }
|
|
Packit |
c5a612 |
"eol" { return EOL; }
|
|
Packit |
c5a612 |
"maxseg" { return MAXSEG; }
|
|
Packit |
c5a612 |
"noop" { return NOOP; }
|
|
Packit |
c5a612 |
"sack" { return SACK; }
|
|
Packit |
c5a612 |
"sack0" { return SACK0; }
|
|
Packit |
c5a612 |
"sack1" { return SACK1; }
|
|
Packit |
c5a612 |
"sack2" { return SACK2; }
|
|
Packit |
c5a612 |
"sack3" { return SACK3; }
|
|
Packit |
c5a612 |
"sack-permitted" { return SACK_PERMITTED; }
|
|
Packit |
c5a612 |
"timestamp" { return TIMESTAMP; }
|
|
Packit |
c5a612 |
"time" { return TIME; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"kind" { return KIND; }
|
|
Packit |
c5a612 |
"count" { return COUNT; }
|
|
Packit |
c5a612 |
"left" { return LEFT; }
|
|
Packit |
c5a612 |
"right" { return RIGHT; }
|
|
Packit |
c5a612 |
"tsval" { return TSVAL; }
|
|
Packit |
c5a612 |
"tsecr" { return TSECR; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"icmp" { return ICMP; }
|
|
Packit |
c5a612 |
"code" { return CODE; }
|
|
Packit |
c5a612 |
"sequence" { return SEQUENCE; }
|
|
Packit |
c5a612 |
"gateway" { return GATEWAY; }
|
|
Packit |
c5a612 |
"mtu" { return MTU; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"igmp" { return IGMP; }
|
|
Packit |
c5a612 |
"mrt" { return MRT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ip6" { return IP6; }
|
|
Packit |
c5a612 |
"priority" { return PRIORITY; }
|
|
Packit |
c5a612 |
"flowlabel" { return FLOWLABEL; }
|
|
Packit |
c5a612 |
"nexthdr" { return NEXTHDR; }
|
|
Packit |
c5a612 |
"hoplimit" { return HOPLIMIT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"icmpv6" { return ICMP6; }
|
|
Packit |
c5a612 |
"param-problem" { return PPTR; }
|
|
Packit |
c5a612 |
"max-delay" { return MAXDELAY; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ah" { return AH; }
|
|
Packit |
c5a612 |
"reserved" { return RESERVED; }
|
|
Packit |
c5a612 |
"spi" { return SPI; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"esp" { return ESP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"comp" { return COMP; }
|
|
Packit |
c5a612 |
"flags" { return FLAGS; }
|
|
Packit |
c5a612 |
"cpi" { return CPI; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"udp" { return UDP; }
|
|
Packit |
c5a612 |
"udplite" { return UDPLITE; }
|
|
Packit |
c5a612 |
"sport" { return SPORT; }
|
|
Packit |
c5a612 |
"dport" { return DPORT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"tcp" { return TCP; }
|
|
Packit |
c5a612 |
"ackseq" { return ACKSEQ; }
|
|
Packit |
c5a612 |
"doff" { return DOFF; }
|
|
Packit |
c5a612 |
"window" { return WINDOW; }
|
|
Packit |
c5a612 |
"urgptr" { return URGPTR; }
|
|
Packit |
c5a612 |
"option" { return OPTION; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"dccp" { return DCCP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"sctp" { return SCTP; }
|
|
Packit |
c5a612 |
"vtag" { return VTAG; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"rt" { return RT; }
|
|
Packit |
c5a612 |
"rt0" { return RT0; }
|
|
Packit |
c5a612 |
"rt2" { return RT2; }
|
|
Packit |
c5a612 |
"srh" { return RT4; }
|
|
Packit |
c5a612 |
"seg-left" { return SEG_LEFT; }
|
|
Packit |
c5a612 |
"addr" { return ADDR; }
|
|
Packit |
c5a612 |
"last-entry" { return LAST_ENT; }
|
|
Packit |
c5a612 |
"tag" { return TAG; }
|
|
Packit |
c5a612 |
"sid" { return SID; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"hbh" { return HBH; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"frag" { return FRAG; }
|
|
Packit |
c5a612 |
"reserved2" { return RESERVED2; }
|
|
Packit |
c5a612 |
"more-fragments" { return MORE_FRAGMENTS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"dst" { return DST; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"mh" { return MH; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"meta" { return META; }
|
|
Packit |
c5a612 |
"mark" { return MARK; }
|
|
Packit |
c5a612 |
"iif" { return IIF; }
|
|
Packit |
c5a612 |
"iifname" { return IIFNAME; }
|
|
Packit |
c5a612 |
"iiftype" { return IIFTYPE; }
|
|
Packit |
c5a612 |
"oif" { return OIF; }
|
|
Packit |
c5a612 |
"oifname" { return OIFNAME; }
|
|
Packit |
c5a612 |
"oiftype" { return OIFTYPE; }
|
|
Packit |
c5a612 |
"skuid" { return SKUID; }
|
|
Packit |
c5a612 |
"skgid" { return SKGID; }
|
|
Packit |
c5a612 |
"nftrace" { return NFTRACE; }
|
|
Packit |
c5a612 |
"rtclassid" { return RTCLASSID; }
|
|
Packit |
c5a612 |
"ibriport" { return IBRIPORT; }
|
|
Packit |
c5a612 |
"ibrname" { return IBRIDGENAME; }
|
|
Packit |
c5a612 |
"obriport" { return OBRIPORT; }
|
|
Packit |
c5a612 |
"obrname" { return OBRIDGENAME; }
|
|
Packit |
c5a612 |
"pkttype" { return PKTTYPE; }
|
|
Packit |
c5a612 |
"cpu" { return CPU; }
|
|
Packit |
c5a612 |
"iifgroup" { return IIFGROUP; }
|
|
Packit |
c5a612 |
"oifgroup" { return OIFGROUP; }
|
|
Packit |
c5a612 |
"cgroup" { return CGROUP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"classid" { return CLASSID; }
|
|
Packit |
c5a612 |
"nexthop" { return NEXTHOP; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ct" { return CT; }
|
|
Packit |
c5a612 |
"l3proto" { return L3PROTOCOL; }
|
|
Packit |
c5a612 |
"proto-src" { return PROTO_SRC; }
|
|
Packit |
c5a612 |
"proto-dst" { return PROTO_DST; }
|
|
Packit |
c5a612 |
"zone" { return ZONE; }
|
|
Packit |
c5a612 |
"original" { return ORIGINAL; }
|
|
Packit |
c5a612 |
"reply" { return REPLY; }
|
|
Packit |
c5a612 |
"direction" { return DIRECTION; }
|
|
Packit |
c5a612 |
"event" { return EVENT; }
|
|
Packit |
c5a612 |
"expectation" { return EXPECTATION; }
|
|
Packit |
c5a612 |
"expiration" { return EXPIRATION; }
|
|
Packit |
c5a612 |
"helper" { return HELPER; }
|
|
Packit |
c5a612 |
"helpers" { return HELPERS; }
|
|
Packit |
c5a612 |
"label" { return LABEL; }
|
|
Packit |
c5a612 |
"state" { return STATE; }
|
|
Packit |
c5a612 |
"status" { return STATUS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"numgen" { return NUMGEN; }
|
|
Packit |
c5a612 |
"inc" { return INC; }
|
|
Packit |
c5a612 |
"mod" { return MOD; }
|
|
Packit |
c5a612 |
"offset" { return OFFSET; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"jhash" { return JHASH; }
|
|
Packit |
c5a612 |
"symhash" { return SYMHASH; }
|
|
Packit |
c5a612 |
"seed" { return SEED; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"dup" { return DUP; }
|
|
Packit |
c5a612 |
"fwd" { return FWD; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"fib" { return FIB; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"osf" { return OSF; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"synproxy" { return SYNPROXY; }
|
|
Packit |
c5a612 |
"mss" { return MSS; }
|
|
Packit |
c5a612 |
"wscale" { return WSCALE; }
|
|
Packit |
c5a612 |
"sack-perm" { return SACKPERM; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"notrack" { return NOTRACK; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"options" { return OPTIONS; }
|
|
Packit |
c5a612 |
"all" { return ALL; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"xml" { return XML; }
|
|
Packit |
c5a612 |
"json" { return JSON; }
|
|
Packit |
c5a612 |
"vm" { return VM; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"exists" { return EXISTS; }
|
|
Packit |
c5a612 |
"missing" { return MISSING; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"exthdr" { return EXTHDR; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"ipsec" { return IPSEC; }
|
|
Packit |
c5a612 |
"mode" { return MODE; }
|
|
Packit |
c5a612 |
"reqid" { return REQID; }
|
|
Packit |
c5a612 |
"spnum" { return SPNUM; }
|
|
Packit |
c5a612 |
"transport" { return TRANSPORT; }
|
|
Packit |
c5a612 |
"tunnel" { return TUNNEL; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"in" { return IN; }
|
|
Packit |
c5a612 |
"out" { return OUT; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
"secmark" { return SECMARK; }
|
|
Packit |
c5a612 |
"secmarks" { return SECMARKS; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{addrstring} {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{ip6addr_rfc2732} {
|
|
Packit |
c5a612 |
yytext[yyleng - 1] = '\0';
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext + 1);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{timestring} {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{numberstring} {
|
|
Packit |
c5a612 |
errno = 0;
|
|
Packit |
c5a612 |
yylval->val = strtoull(yytext, NULL, 0);
|
|
Packit |
c5a612 |
if (errno != 0) {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
return NUM;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{classid}/[ \t\n:\-},] {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{quotedstring} {
|
|
Packit |
c5a612 |
yytext[yyleng - 1] = '\0';
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext + 1);
|
|
Packit |
c5a612 |
return QUOTED_STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{asteriskstring} {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return ASTERISK_STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{string} {
|
|
Packit |
c5a612 |
yylval->string = xstrdup(yytext);
|
|
Packit |
c5a612 |
return STRING;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
\\{newline} {
|
|
Packit |
c5a612 |
reset_pos(yyget_extra(yyscanner), yylloc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{newline} {
|
|
Packit |
c5a612 |
reset_pos(yyget_extra(yyscanner), yylloc);
|
|
Packit |
c5a612 |
return NEWLINE;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
{tab}+
|
|
Packit |
c5a612 |
{space}+
|
|
Packit |
c5a612 |
{comment}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
<<EOF>> {
|
|
Packit |
c5a612 |
update_pos(yyget_extra(yyscanner), yylloc, 1);
|
|
Packit |
c5a612 |
scanner_pop_buffer(yyscanner);
|
|
Packit |
c5a612 |
if (YY_CURRENT_BUFFER == NULL)
|
|
Packit |
c5a612 |
return TOKEN_EOF;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
. { return JUNK; }
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
%%
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void scanner_pop_buffer(yyscan_t scanner)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
yypop_buffer_state(scanner);
|
|
Packit |
c5a612 |
state->indesc = state->indescs[--state->indesc_idx];
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void scanner_push_file(struct nft_ctx *nft, void *scanner,
|
|
Packit |
c5a612 |
const char *filename, const struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
struct input_descriptor *indesc;
|
|
Packit |
c5a612 |
YY_BUFFER_STATE b;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
b = yy_create_buffer(nft->f[state->indesc_idx], YY_BUF_SIZE, scanner);
|
|
Packit |
c5a612 |
yypush_buffer_state(b, scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
indesc = xzalloc(sizeof(struct input_descriptor));
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (loc != NULL)
|
|
Packit |
c5a612 |
indesc->location = *loc;
|
|
Packit |
c5a612 |
indesc->type = INDESC_FILE;
|
|
Packit |
c5a612 |
indesc->name = xstrdup(filename);
|
|
Packit |
c5a612 |
init_pos(indesc);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
state->indescs[state->indesc_idx] = indesc;
|
|
Packit |
c5a612 |
state->indesc = state->indescs[state->indesc_idx++];
|
|
Packit |
c5a612 |
list_add_tail(&indesc->list, &state->indesc_list);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static int include_file(struct nft_ctx *nft, void *scanner,
|
|
Packit |
c5a612 |
const char *filename, const struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
struct error_record *erec;
|
|
Packit |
c5a612 |
FILE *f;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (state->indesc_idx == MAX_INCLUDE_DEPTH) {
|
|
Packit |
c5a612 |
erec = error(loc, "Include nested too deeply, max %u levels",
|
|
Packit |
c5a612 |
MAX_INCLUDE_DEPTH);
|
|
Packit |
c5a612 |
goto err;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
f = fopen(filename, "r");
|
|
Packit |
c5a612 |
if (f == NULL) {
|
|
Packit |
c5a612 |
erec = error(loc, "Could not open file \"%s\": %s\n",
|
|
Packit |
c5a612 |
filename, strerror(errno));
|
|
Packit |
c5a612 |
goto err;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
nft->f[state->indesc_idx] = f;
|
|
Packit |
c5a612 |
scanner_push_file(nft, scanner, filename, loc);
|
|
Packit |
c5a612 |
return 0;
|
|
Packit |
c5a612 |
err:
|
|
Packit |
c5a612 |
erec_queue(erec, state->msgs);
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static int include_glob(struct nft_ctx *nft, void *scanner, const char *pattern,
|
|
Packit |
c5a612 |
const struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
struct error_record *erec = NULL;
|
|
Packit |
c5a612 |
bool wildcard = false;
|
|
Packit |
c5a612 |
glob_t glob_data;
|
|
Packit |
c5a612 |
unsigned int i;
|
|
Packit |
c5a612 |
int flags = 0;
|
|
Packit |
c5a612 |
int ret;
|
|
Packit |
c5a612 |
char *p;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* This function can return four meaningful values:
|
|
Packit |
c5a612 |
*
|
|
Packit |
c5a612 |
* -1 means that there was an error.
|
|
Packit |
c5a612 |
* 0 means that a single non-wildcard match was done.
|
|
Packit |
c5a612 |
* 1 means that there are no wildcards in the pattern and the
|
|
Packit |
c5a612 |
* search can continue.
|
|
Packit |
c5a612 |
* 2 means that there are wildcards in the pattern and the search
|
|
Packit |
c5a612 |
* can continue.
|
|
Packit |
c5a612 |
*
|
|
Packit |
c5a612 |
* The diffrence is needed, because there is a semantic difference
|
|
Packit |
c5a612 |
* between patterns with wildcards and no wildcards. Not finding a
|
|
Packit |
c5a612 |
* non-wildcard file is an error but not finding any matches for a
|
|
Packit |
c5a612 |
* wildcard pattern is not.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* There shouldn't be a need to use escape characters in include paths.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
flags |= GLOB_NOESCAPE;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* Mark directories so we can filter them out (also links). */
|
|
Packit |
c5a612 |
flags |= GLOB_MARK;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* If there is no match, glob() doesn't set GLOB_MAGCHAR even if there
|
|
Packit |
c5a612 |
* are wildcard characters in the pattern. We need to look for (luckily
|
|
Packit |
c5a612 |
* well-known and not likely to change) magic characters ourselves. In a
|
|
Packit |
c5a612 |
* perfect world, we could use glob() itself to figure out if there are
|
|
Packit |
c5a612 |
* wildcards in the pattern.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
p = (char *)pattern;
|
|
Packit |
c5a612 |
while (*p) {
|
|
Packit |
c5a612 |
if (*p == '*' || *p == '?' || *p == '[') {
|
|
Packit |
c5a612 |
wildcard = true;
|
|
Packit |
c5a612 |
break;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
p++;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
ret = glob(pattern, flags, NULL, &glob_data);
|
|
Packit |
c5a612 |
if (ret == 0) {
|
|
Packit |
c5a612 |
char *path;
|
|
Packit |
c5a612 |
int len;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* reverse alphabetical order due to stack */
|
|
Packit |
c5a612 |
for (i = glob_data.gl_pathc; i > 0; i--) {
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
path = glob_data.gl_pathv[i-1];
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* ignore directories */
|
|
Packit |
c5a612 |
len = strlen(path);
|
|
Packit |
c5a612 |
if (len == 0 || path[len - 1] == '/')
|
|
Packit |
c5a612 |
continue;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
ret = include_file(nft, scanner, path, loc);
|
|
Packit |
c5a612 |
if (ret != 0)
|
|
Packit |
c5a612 |
goto err;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
globfree(&glob_data);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* If no wildcards and we found the file, stop the search (with
|
|
Packit |
c5a612 |
* 0). In case of wildcards we need to still continue the
|
|
Packit |
c5a612 |
* search, because other matches might be in other include
|
|
Packit |
c5a612 |
* directories. We handled the case with a non-wildcard pattern
|
|
Packit |
c5a612 |
* and no matches already before.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
return wildcard ? 2 : 0;
|
|
Packit |
c5a612 |
} else if (ret == GLOB_NOMATCH) {
|
|
Packit |
c5a612 |
globfree(&glob_data);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* We need to tell the caller whether wildcards were used in
|
|
Packit |
c5a612 |
* case of no match, because the semantics for handling the
|
|
Packit |
c5a612 |
* cases are different.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
return wildcard ? 2 : 1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
erec = error(loc, "Failed to glob the pattern %s", pattern);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* intentional fall through */
|
|
Packit |
c5a612 |
err:
|
|
Packit |
c5a612 |
if (erec)
|
|
Packit |
c5a612 |
erec_queue(erec, state->msgs);
|
|
Packit |
c5a612 |
globfree(&glob_data);
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
int scanner_read_file(struct nft_ctx *nft, const char *filename,
|
|
Packit |
c5a612 |
const struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
return include_file(nft, nft->scanner, filename, loc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static bool search_in_include_path(const char *filename)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
return (strncmp(filename, "./", strlen("./")) != 0 &&
|
|
Packit |
c5a612 |
strncmp(filename, "../", strlen("../")) != 0 &&
|
|
Packit |
c5a612 |
filename[0] != '/');
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
int scanner_include_file(struct nft_ctx *nft, void *scanner,
|
|
Packit |
c5a612 |
const char *filename, const struct location *loc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
struct error_record *erec;
|
|
Packit |
c5a612 |
char buf[PATH_MAX];
|
|
Packit |
c5a612 |
unsigned int i;
|
|
Packit |
c5a612 |
int ret = -1;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (search_in_include_path(filename)) {
|
|
Packit |
c5a612 |
for (i = 0; i < nft->num_include_paths; i++) {
|
|
Packit |
c5a612 |
ret = snprintf(buf, sizeof(buf), "%s/%s",
|
|
Packit |
c5a612 |
nft->include_paths[i], filename);
|
|
Packit |
c5a612 |
if (ret < 0 || ret >= PATH_MAX) {
|
|
Packit |
c5a612 |
erec = error(loc, "Too long file path \"%s/%s\"\n",
|
|
Packit |
c5a612 |
nft->include_paths[i], filename);
|
|
Packit |
c5a612 |
erec_queue(erec, state->msgs);
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
ret = include_glob(nft, scanner, buf, loc);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* error was already handled */
|
|
Packit |
c5a612 |
if (ret == -1)
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
/* no wildcards and file was processed: break early. */
|
|
Packit |
c5a612 |
if (ret == 0)
|
|
Packit |
c5a612 |
return 0;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* else 1 (no wildcards) or 2 (wildcards): keep
|
|
Packit |
c5a612 |
* searching.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
} else {
|
|
Packit |
c5a612 |
/* an absolute path (starts with '/') */
|
|
Packit |
c5a612 |
ret = include_glob(nft, scanner, filename, loc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* handle the case where no file was found */
|
|
Packit |
c5a612 |
if (ret == -1)
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
else if (ret == 0 || ret == 2)
|
|
Packit |
c5a612 |
return 0;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
/* 1 means an error, because there are no more include directories to
|
|
Packit |
c5a612 |
* search, and the pattern does not have wildcard characters.
|
|
Packit |
c5a612 |
*/
|
|
Packit |
c5a612 |
erec = error(loc, "File not found: %s", filename);
|
|
Packit |
c5a612 |
erec_queue(erec, state->msgs);
|
|
Packit |
c5a612 |
return -1;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
void scanner_push_buffer(void *scanner, const struct input_descriptor *indesc,
|
|
Packit |
c5a612 |
const char *buffer)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(scanner);
|
|
Packit |
c5a612 |
YY_BUFFER_STATE b;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
state->indesc = xzalloc(sizeof(struct input_descriptor));
|
|
Packit |
c5a612 |
state->indescs[state->indesc_idx] = state->indesc;
|
|
Packit |
c5a612 |
state->indesc_idx++;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
memcpy(state->indesc, indesc, sizeof(*state->indesc));
|
|
Packit |
c5a612 |
state->indesc->data = buffer;
|
|
Packit |
c5a612 |
state->indesc->name = NULL;
|
|
Packit |
c5a612 |
list_add_tail(&state->indesc->list, &state->indesc_list);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
b = yy_scan_string(buffer, scanner);
|
|
Packit |
c5a612 |
assert(b != NULL);
|
|
Packit |
c5a612 |
init_pos(state->indesc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
void *scanner_init(struct parser_state *state)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
yyscan_t scanner;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
yylex_init_extra(state, &scanner);
|
|
Packit |
c5a612 |
yyset_out(NULL, scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
return scanner;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void input_descriptor_destroy(const struct input_descriptor *indesc)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
if (indesc->name)
|
|
Packit |
c5a612 |
xfree(indesc->name);
|
|
Packit |
c5a612 |
xfree(indesc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
static void input_descriptor_list_destroy(struct parser_state *state)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct input_descriptor *indesc, *next;
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
list_for_each_entry_safe(indesc, next, &state->indesc_list, list) {
|
|
Packit |
c5a612 |
list_del(&indesc->list);
|
|
Packit |
c5a612 |
input_descriptor_destroy(indesc);
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
void scanner_destroy(struct nft_ctx *nft)
|
|
Packit |
c5a612 |
{
|
|
Packit |
c5a612 |
struct parser_state *state = yyget_extra(nft->scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
do {
|
|
Packit |
c5a612 |
yypop_buffer_state(nft->scanner);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
if (nft->f[state->indesc_idx]) {
|
|
Packit |
c5a612 |
fclose(nft->f[state->indesc_idx]);
|
|
Packit |
c5a612 |
nft->f[state->indesc_idx] = NULL;
|
|
Packit |
c5a612 |
}
|
|
Packit |
c5a612 |
} while (state->indesc_idx--);
|
|
Packit |
c5a612 |
|
|
Packit |
c5a612 |
input_descriptor_list_destroy(state);
|
|
Packit |
c5a612 |
yylex_destroy(nft->scanner);
|
|
Packit |
c5a612 |
}
|