mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-02 12:20:51 +00:00
Fix one parsing bug introduced by last commit, and correct parsing
and printing of or-blocks in address, ports and options lists.
This commit is contained in:
parent
ac4ed01f56
commit
8ed2d7497b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101641
@ -178,6 +178,8 @@ enum tokens {
|
||||
|
||||
TOK_OR,
|
||||
TOK_NOT,
|
||||
TOK_STARTBRACE,
|
||||
TOK_ENDBRACE,
|
||||
|
||||
TOK_ACCEPT,
|
||||
TOK_COUNT,
|
||||
@ -323,6 +325,10 @@ struct _s_x rule_options[] = {
|
||||
{ "!", /* escape ? */ TOK_NOT }, /* pseudo option */
|
||||
{ "or", TOK_OR }, /* pseudo option */
|
||||
{ "|", /* escape */ TOK_OR }, /* pseudo option */
|
||||
{ "{", TOK_STARTBRACE }, /* pseudo option */
|
||||
{ "(", TOK_STARTBRACE }, /* pseudo option */
|
||||
{ "}", TOK_ENDBRACE }, /* pseudo option */
|
||||
{ ")", TOK_ENDBRACE }, /* pseudo option */
|
||||
{ NULL, TOK_NULL },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
@ -935,6 +941,8 @@ show_ipfw(struct ip_fw *rule)
|
||||
HAVE_PROTO|HAVE_SRCIP|HAVE_DSTIP);
|
||||
case O_IP_SRCPORT:
|
||||
show_prerequisites(&flags, HAVE_PROTO|HAVE_SRCIP);
|
||||
if ((cmd->len & F_OR) && !or_block)
|
||||
printf(" {");
|
||||
print_newports((ipfw_insn_u16 *)cmd, proto);
|
||||
break;
|
||||
|
||||
@ -1696,7 +1704,7 @@ delete(int ac, char *av[])
|
||||
else if (!strncmp(*av, "enable", strlen(*av)))
|
||||
do_set = 3; /* enable set */
|
||||
av++; ac--;
|
||||
if (!strncmp(*av, "set", strlen(*av))) {
|
||||
if (ac > 0 && !strncmp(*av, "set", strlen(*av))) {
|
||||
if (do_set == 0)
|
||||
do_set = 1; /* delete set */
|
||||
ac--; av++;
|
||||
@ -2407,6 +2415,7 @@ add(int ac, char *av[])
|
||||
if (ac && (*av[0] == '(' || *av[0] == '{')) { \
|
||||
if (open_par) \
|
||||
errx(EX_USAGE, "nested \"(\" not allowed\n"); \
|
||||
prev = NULL; \
|
||||
open_par = 1; \
|
||||
if ( (av[0])[1] == '\0') { \
|
||||
ac--; av++; \
|
||||
@ -2421,6 +2430,7 @@ add(int ac, char *av[])
|
||||
if (ac && ( \
|
||||
!strncmp(*av, ")", strlen(*av)) || \
|
||||
!strncmp(*av, "}", strlen(*av)) )) { \
|
||||
prev = NULL; \
|
||||
open_par = 0; \
|
||||
ac--; av++; \
|
||||
} else \
|
||||
@ -2508,17 +2518,24 @@ add(int ac, char *av[])
|
||||
cmd = next_cmd(cmd);
|
||||
OR_BLOCK(source_ip);
|
||||
|
||||
OR_START(source_port);
|
||||
/*
|
||||
* source ports, optional
|
||||
*/
|
||||
NOT_BLOCK; /* optional "not" */
|
||||
if (ac && fill_newports((ipfw_insn_u16 *)cmd, *av, proto)) {
|
||||
/* XXX todo: check that we have a protocol with ports */
|
||||
cmd->opcode = O_IP_SRCPORT;
|
||||
ac--;
|
||||
av++;
|
||||
cmd = next_cmd(cmd);
|
||||
if (ac) {
|
||||
if (!strncmp(*av, "any", strlen(*av))) {
|
||||
ac--;
|
||||
av++;
|
||||
} else if (fill_newports((ipfw_insn_u16 *)cmd, *av, proto)) {
|
||||
/* XXX todo: check that we have a protocol with ports */
|
||||
cmd->opcode = O_IP_SRCPORT;
|
||||
ac--;
|
||||
av++;
|
||||
cmd = next_cmd(cmd);
|
||||
}
|
||||
}
|
||||
OR_BLOCK(source_port);
|
||||
|
||||
read_to:
|
||||
/*
|
||||
@ -2552,23 +2569,33 @@ add(int ac, char *av[])
|
||||
cmd = next_cmd(cmd);
|
||||
OR_BLOCK(dest_ip);
|
||||
|
||||
OR_START(dest_port);
|
||||
/*
|
||||
* dest. ports, optional
|
||||
*/
|
||||
NOT_BLOCK; /* optional "not" */
|
||||
if (ac && fill_newports((ipfw_insn_u16 *)cmd, *av, proto)) {
|
||||
/* XXX todo: check that we have a protocol with ports */
|
||||
cmd->opcode = O_IP_DSTPORT;
|
||||
ac--;
|
||||
av++;
|
||||
cmd += F_LEN(cmd);
|
||||
if (ac) {
|
||||
if (!strncmp(*av, "any", strlen(*av))) {
|
||||
ac--;
|
||||
av++;
|
||||
} else if (fill_newports((ipfw_insn_u16 *)cmd, *av, proto)) {
|
||||
/* XXX todo: check that we have a protocol with ports */
|
||||
cmd->opcode = O_IP_DSTPORT;
|
||||
ac--;
|
||||
av++;
|
||||
cmd += F_LEN(cmd);
|
||||
}
|
||||
}
|
||||
OR_BLOCK(dest_port);
|
||||
|
||||
read_options:
|
||||
prev = NULL;
|
||||
while (ac) {
|
||||
char *s = *av;
|
||||
ipfw_insn_u32 *cmd32 = (ipfw_insn_u32 *)cmd; /* alias */
|
||||
char *s;
|
||||
ipfw_insn_u32 *cmd32; /* alias for cmd */
|
||||
|
||||
s = *av;
|
||||
cmd32 = (ipfw_insn_u32 *)cmd;
|
||||
|
||||
if (*s == '!') { /* alternate syntax for NOT */
|
||||
if (cmd->len & F_NOT)
|
||||
@ -2586,11 +2613,23 @@ add(int ac, char *av[])
|
||||
break;
|
||||
|
||||
case TOK_OR:
|
||||
if (prev == NULL)
|
||||
if (open_par == 0 || prev == NULL)
|
||||
errx(EX_USAGE, "invalid \"or\" block\n");
|
||||
prev->len |= F_OR;
|
||||
break;
|
||||
|
||||
|
||||
case TOK_STARTBRACE:
|
||||
if (open_par)
|
||||
errx(EX_USAGE, "+nested \"(\" not allowed\n");
|
||||
open_par = 1;
|
||||
break;
|
||||
|
||||
case TOK_ENDBRACE:
|
||||
if (!open_par)
|
||||
errx(EX_USAGE, "+missing \")\"\n");
|
||||
open_par = 0;
|
||||
break;
|
||||
|
||||
case TOK_IN:
|
||||
fill_cmd(cmd, O_IN, 0, 0);
|
||||
break;
|
||||
@ -2750,6 +2789,9 @@ add(int ac, char *av[])
|
||||
break;
|
||||
|
||||
case TOK_KEEPSTATE:
|
||||
if (open_par)
|
||||
errx(EX_USAGE, "keep-state cannot be part "
|
||||
"of an or block");
|
||||
if (have_state)
|
||||
errx(EX_USAGE, "only one of keep-state "
|
||||
"and limit is allowed");
|
||||
@ -2758,10 +2800,13 @@ add(int ac, char *av[])
|
||||
break;
|
||||
|
||||
case TOK_LIMIT:
|
||||
NEED1("limit needs mask and # of connections");
|
||||
if (open_par)
|
||||
errx(EX_USAGE, "limit cannot be part "
|
||||
"of an or block");
|
||||
if (have_state)
|
||||
errx(EX_USAGE, "only one of keep-state "
|
||||
"and limit is allowed");
|
||||
NEED1("limit needs mask and # of connections");
|
||||
have_state = cmd;
|
||||
{
|
||||
ipfw_insn_limit *c = (ipfw_insn_limit *)cmd;
|
||||
|
Loading…
Reference in New Issue
Block a user