rinetd/parse.peg
2017-09-05 17:27:16 +02:00

107 lines
3.1 KiB
Plaintext

%{
#define YY_CTX_LOCAL 1
#define YY_CTX_MEMBERS \
FILE *fp; \
int isAuthAllow; \
char *tmpPort; \
int tmpPortNum, tmpProto; \
int bindPortNum, bindProto, connectPortNum, connectProto; \
char *bindAddress, *connectAddress;
#define YY_INPUT(yyctx, buf, result, max_size) \
{ \
int yyc = fgetc(yyctx->fp); \
result = (EOF == yyc) ? 0 : (*(buf) = yyc, 1); \
}
#define PARSE_ERROR exit(1);
%}
file = (line | invalid-syntax)*
line = -? (command -?)? comment? eol
command = (server | rule | logfile | pidlogfile | logcommon)
comment = "#" (!eol .)*
server = bind-address - bind-port - connect-address - connect-port {
addServer(yy->bindAddress, yy->bindPortNum, yy->bindProto,
yy->connectAddress, yy->connectPortNum, yy->connectProto);
yy->bindAddress = yy->connectAddress = NULL;
}
bind-address = < ipv4 > { yy->bindAddress = strdup(yytext); }
connect-address = < ipv4 > { yy->connectAddress = strdup(yytext); }
bind-port = full-port { yy->bindPortNum = yy->tmpPortNum; yy->bindProto = yy->tmpProto; }
connect-port = full-port { yy->connectPortNum = yy->tmpPortNum; yy->connectProto = yy->tmpProto; }
full-port = port proto {
char const *proto = yy->tmpProto == protoTcp ? "tcp" : "udp";
struct servent *service = getservbyname(yy->tmpPort, proto);
yy->tmpPortNum = service ? ntohs(service->s_port) : atoi(yy->tmpPort);
if (yy->tmpPortNum == 0 || yy->tmpPortNum >= 65536) {
syslog(LOG_ERR, "port %s/%s missing or out of range\n", yy->tmpPort, proto);
PARSE_ERROR;
}
}
port = < (number | service) > { yy->tmpPort = strdup(yytext); }
proto = '/tcp' { yy->tmpProto = protoTcp; }
| '/udp' { yy->tmpProto = protoUdp; }
| '' { yy->tmpProto = protoTcp; }
rule = auth-key - < pattern > {
allRules = (Rule *)
realloc(allRules, sizeof(Rule) * (allRulesCount + 1));
if (!allRules) {
PARSE_ERROR;
}
allRules[allRulesCount].pattern = strdup(yytext);
if (!allRules[allRulesCount].pattern) {
PARSE_ERROR;
}
allRules[allRulesCount].type = yy->isAuthAllow ? allowRule : denyRule;
if (seTotal > 0) {
if (seInfo[seTotal - 1].rulesStart == 0) {
seInfo[seTotal - 1].rulesStart = allRulesCount;
}
++seInfo[seTotal - 1].rulesCount;
} else {
++globalRulesCount;
}
++allRulesCount;
}
auth-key = < ("allow" | "deny") > { yy->isAuthAllow = (yytext[0] == 'a'); }
logfile = "logfile" - < filename > {
logFileName = strdup(yytext);
if (!logFileName) {
PARSE_ERROR;
}
}
pidlogfile = "pidlogfile" - < filename > {
pidLogFileName = strdup(yytext);
if (!pidLogFileName) {
PARSE_ERROR;
}
}
logcommon = "logcommon" {
logFormatCommon = 1;
}
invalid-syntax = < (!eol .)* > eol { PARSE_ERROR; /* FIXME */ }
service = name
ipv4 = number [.] number [.] number [.] number | '0'
pattern = [0-9*?]+ ('.' [0-9*?]+ ('.' [0-9*?]+ ('.' [0-9*?]+)?)?)?
number = digit+
name = [a-zA-Z][a-zA-Z0-9_]*
filename = '"' [^"]+ '"'
| [^ \t\r\n]+
- = [ \t]+
digit = [0-9]
eol = '\r'? '\n' | eof
eof = '\0'