Two bugfixes:

+ the header file contains two different opcodes (O_IPOPTS and O_IPOPT)
    for what is the same thing, and sure enough i used one in the kernel
    and the other one in userland. Be consistent!

  + "keep-state" and "limit" must be the last match pattern in a rule,
    so no matter how you enter them move them to the end of the rule.
This commit is contained in:
Luigi Rizzo 2002-07-31 22:31:47 +00:00
parent 5aae45c2e6
commit 52bc23ab8a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101116

View File

@ -996,7 +996,7 @@ show_ipfw(struct ip_fw *rule)
printf(" iplen %u", cmd->arg1 ); printf(" iplen %u", cmd->arg1 );
break; break;
case O_IPOPTS: case O_IPOPT:
print_flags("ipoptions", cmd, f_ipopts); print_flags("ipoptions", cmd, f_ipopts);
break; break;
@ -2170,7 +2170,7 @@ add(int ac, char *av[])
* various flags used to record that we entered some fields. * various flags used to record that we entered some fields.
*/ */
int have_mac = 0; /* set if we have a MAC address */ int have_mac = 0; /* set if we have a MAC address */
int have_state = 0; /* check-state or keep-state */ ipfw_insn *have_state = NULL; /* check-state or keep-state */
int i; int i;
@ -2219,7 +2219,7 @@ add(int ac, char *av[])
action->len = 1; /* default */ action->len = 1; /* default */
switch(i) { switch(i) {
case TOK_CHECKSTATE: case TOK_CHECKSTATE:
have_state = 1; have_state = action;
action->opcode = O_CHECK_STATE; action->opcode = O_CHECK_STATE;
break; break;
@ -2344,10 +2344,8 @@ add(int ac, char *av[])
cmd = next_cmd(cmd); cmd = next_cmd(cmd);
} }
if (have_state) { if (have_state) /* must be a check-state, we are done */
have_state = 0;
goto done; goto done;
}
#define OR_START(target) \ #define OR_START(target) \
if (ac && (*av[0] == '(' || *av[0] == '{')) { \ if (ac && (*av[0] == '(' || *av[0] == '{')) { \
@ -2610,13 +2608,13 @@ add(int ac, char *av[])
case TOK_IPOPTS: case TOK_IPOPTS:
NEED1("missing argument for ipoptions"); NEED1("missing argument for ipoptions");
fill_flags(cmd, O_IPOPTS, f_ipopts, *av); fill_flags(cmd, O_IPOPT, f_ipopts, *av);
ac--; av++; ac--; av++;
break; break;
case TOK_IPTOS: case TOK_IPTOS:
NEED1("missing argument for iptos"); NEED1("missing argument for iptos");
fill_flags(cmd, O_IPOPTS, f_iptos, *av); fill_flags(cmd, O_IPTOS, f_iptos, *av);
ac--; av++; ac--; av++;
break; break;
@ -2697,17 +2695,18 @@ add(int ac, char *av[])
case TOK_KEEPSTATE: case TOK_KEEPSTATE:
if (have_state) if (have_state)
errx(EX_USAGE, "only one of check-state " errx(EX_USAGE, "only one of keep-state "
"and limit is allowed"); "and limit is allowed");
have_state = 1; have_state = cmd;
fill_cmd(cmd, O_KEEP_STATE, 0, 0); fill_cmd(cmd, O_KEEP_STATE, 0, 0);
break; break;
case TOK_LIMIT: case TOK_LIMIT:
NEED1("limit needs mask and # of connections"); NEED1("limit needs mask and # of connections");
if (have_state) if (have_state)
errx(EX_USAGE, "only one of check-state " errx(EX_USAGE, "only one of keep-state "
"and limit is allowed"); "and limit is allowed");
have_state = cmd;
{ {
ipfw_insn_limit *c = (ipfw_insn_limit *)cmd; ipfw_insn_limit *c = (ipfw_insn_limit *)cmd;
@ -2730,7 +2729,6 @@ add(int ac, char *av[])
if (c->limit_mask == 0) if (c->limit_mask == 0)
errx(EX_USAGE, "missing limit mask"); errx(EX_USAGE, "missing limit mask");
ac--; av++; ac--; av++;
have_state = 1;
} }
break; break;
@ -2756,22 +2754,35 @@ add(int ac, char *av[])
/* /*
* generate O_PROBE_STATE if necessary * generate O_PROBE_STATE if necessary
*/ */
if (have_state) { if (have_state && have_state->opcode != O_CHECK_STATE) {
fill_cmd(dst, O_PROBE_STATE, 0, 0); fill_cmd(dst, O_PROBE_STATE, 0, 0);
dst = next_cmd(dst); dst = next_cmd(dst);
} }
/* /*
* copy all commands but O_LOG * copy all commands but O_LOG, O_KEEP_STATE, O_LIMIT
*/ */
for (src = (ipfw_insn *)cmdbuf; src != cmd; src += i) { for (src = (ipfw_insn *)cmdbuf; src != cmd; src += i) {
i = F_LEN(src); i = F_LEN(src);
if (src->opcode != O_LOG) { switch (src->opcode) {
case O_LOG:
case O_KEEP_STATE:
case O_LIMIT:
break;
default:
bcopy(src, dst, i * sizeof(u_int32_t)); bcopy(src, dst, i * sizeof(u_int32_t));
dst += i; dst += i;
} }
} }
/*
* put back the have_state command as last opcode
*/
if (have_state) {
i = F_LEN(have_state);
bcopy(have_state, dst, i * sizeof(u_int32_t));
dst += i;
}
/* /*
* start action section * start action section
*/ */