{ NULL, 0 } /* terminator */
};
+/* index of 'lookup ... ' keys in the kernel */
+static int lookup_key[] = {
+ TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT,
+ TOK_UID, TOK_GID, TOK_JAIL,
+ TOK_PROTO, TOK_MACTYPE, 0, };
+
static struct _s_x rule_options[] = {
{ "tagged", TOK_TAGGED },
{ "uid", TOK_UID },
{ "dst-ip6", TOK_DSTIP6},
{ "src-ipv6", TOK_SRCIP6},
{ "src-ip6", TOK_SRCIP6},
+ { "lookup", TOK_LOOKUP},
{ "//", TOK_COMMENT },
{ "not", TOK_NOT }, /* pseudo option */
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 = "<invalid>";
+
+ if (d < sizeof(lookup_key)/sizeof(lookup_key[0]))
+ arg = match_value(rule_options, lookup_key[d]);
+ printf("%s lookup %s %d,%d", cmd->o.len & F_NOT ? " not": "",
+ arg, cmd->o.arg1, a[0]);
+ 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) {
/*
* 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 ',')
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);
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++;
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);
}
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[,arg]");
+ 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] ; 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++;
+ p = strchr(*av, ',');
+ if (p) {
+ *p++ = '\0';
+ c->d[0] = strtoul(p, NULL, 0);
+ } else {
+ c->d[0] = ~0;
+ }
+ cmd->arg1 = strtoul(*av, NULL, 0);
+ ac--; av++;
+ }
+ break;
+
default:
errx(EX_USAGE, "unrecognised option [%d] %s\n", i, s);
}