X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ipfw%2Fipfw2.c;h=85979f87c5bb2e822bc6039c364fee89a98f526c;hb=6e80cc05e1749db7877ace32b22f29d42499fd6e;hp=8d6ed872f818836671b5edaff8045df062ab7e23;hpb=6c2e192c3237bd46db6ad4230fed71d28f362331;p=ipfw.git diff --git a/ipfw/ipfw2.c b/ipfw/ipfw2.c index 8d6ed87..85979f8 100644 --- a/ipfw/ipfw2.c +++ b/ipfw/ipfw2.c @@ -224,6 +224,15 @@ static struct _s_x rule_action_params[] = { { NULL, 0 } /* terminator */ }; +/* + * The 'lookup' instruction accepts one of the following arguments. + * -1 is a terminator for the list. + * Arguments are passed as v[1] in O_DST_LOOKUP options. + */ +static int lookup_key[] = { + TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT, + TOK_UID, TOK_JAIL, -1 }; + static struct _s_x rule_options[] = { { "tagged", TOK_TAGGED }, { "uid", TOK_UID }, @@ -290,6 +299,7 @@ static struct _s_x rule_options[] = { { "dst-ip6", TOK_DSTIP6}, { "src-ipv6", TOK_SRCIP6}, { "src-ip6", TOK_SRCIP6}, + { "lookup", TOK_LOOKUP}, { "//", TOK_COMMENT }, { "not", TOK_NOT }, /* pseudo option */ @@ -358,8 +368,8 @@ do_cmd(int optname, void *optval, uintptr_t optlen) if (s < 0) err(EX_UNAVAILABLE, "socket"); - if (optname == IP_FW_GET || optname == IP_FW_DYN_GET || - optname == IP_DUMMYNET_GET || + if (optname == IP_FW_GET || optname == IP_DUMMYNET_GET || + optname == IP_FW_DYN_GET || optname == IP_FW_ADD || optname == IP_FW_TABLE_LIST || optname == IP_FW_TABLE_GETSIZE || optname == IP_FW_NAT_GET_CONFIG || @@ -743,6 +753,16 @@ print_ip(ipfw_insn_ip *cmd, char const *s) int len = F_LEN((ipfw_insn *)cmd); uint32_t *a = ((ipfw_insn_u32 *)cmd)->d; + if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) { + uint32_t d = a[1]; + const char *arg = ""; + + if (d < sizeof(lookup_key)/sizeof(lookup_key[0])) + arg = match_value(rule_options, lookup_key[d]); + printf("%s lookup %s %d", cmd->o.len & F_NOT ? " not": "", + arg, cmd->o.arg1); + return; + } printf("%s%s ", cmd->o.len & F_NOT ? " not": "", s); if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) { @@ -1816,7 +1836,6 @@ ipfw_list(int ac, char *av[], int show_counters) bcwidth = width; } } - if (co.do_dynamic && ndyn) { for (n = 0, d = dynrules; n < ndyn; n++, d++) { if (co.use_set) { @@ -1837,7 +1856,6 @@ ipfw_list(int ac, char *av[], int show_counters) bcwidth = width; } } - /* if no rule numbers were specified, list all rules */ if (ac == 0) { for (n = 0, r = data; n < nstat; n++, r = NEXT(r)) { @@ -2758,9 +2776,11 @@ chkarg: /* * In the kernel we assume AF_INET and use only - * sin_port and sin_addr. + * sin_port and sin_addr. Remember to set sin_len as + * the routing code seems to use it too. */ p->sa.sin_family = AF_INET; + p->sa.sin_len = sizeof(struct sockaddr_in); p->sa.sin_port = 0; /* * locate the address-port separator (':' or ',') @@ -2877,7 +2897,7 @@ chkarg: if (have_tag) errx(EX_USAGE, "tag and untag cannot be " "specified more than once"); - GET_UINT_ARG(tag, 1, IPFW_DEFAULT_RULE - 1, i, + GET_UINT_ARG(tag, IPFW_ARG_MIN, IPFW_ARG_MAX, i, rule_action_params); have_tag = cmd; fill_cmd(cmd, O_TAG, (i == TOK_TAG) ? 0: F_NOT, tag); @@ -3354,7 +3374,7 @@ read_options: if (c->limit_mask == 0) errx(EX_USAGE, "limit: missing limit mask"); - GET_UINT_ARG(c->conn_limit, 1, IPFW_DEFAULT_RULE - 1, + GET_UINT_ARG(c->conn_limit, IPFW_ARG_MIN, IPFW_ARG_MAX, TOK_LIMIT, rule_options); ac--; av++; @@ -3482,7 +3502,7 @@ read_options: else { uint16_t tag; - GET_UINT_ARG(tag, 1, IPFW_DEFAULT_RULE - 1, + GET_UINT_ARG(tag, IPFW_ARG_MIN, IPFW_ARG_MAX, TOK_TAGGED, rule_options); fill_cmd(cmd, O_TAGGED, 0, tag); } @@ -3495,6 +3515,31 @@ read_options: ac--; av++; break; + case TOK_LOOKUP: { + ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd; + char *p; + int j; + + if (ac < 2) + errx(EX_USAGE, "format: lookup argument tablenum"); + cmd->opcode = O_IP_DST_LOOKUP; + cmd->len |= F_INSN_SIZE(ipfw_insn) + 2; + i = match_token(rule_options, *av); + for (j = 0; lookup_key[j] >= 0 ; j++) { + if (i == lookup_key[j]) + break; + } + if (lookup_key[j] <= 0) + errx(EX_USAGE, "format: cannot lookup on %s", *av); + c->d[1] = j; // i converted to option + ac--; av++; + cmd->arg1 = strtoul(*av, &p, 0); + if (p && *p) + errx(EX_USAGE, "format: lookup argument tablenum"); + ac--; av++; + } + break; + default: errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s); }