Changeset View
Changeset View
Standalone View
Standalone View
sbin/ipfw/ipfw2.c
Show First 20 Lines • Show All 294 Lines • ▼ Show 20 Lines | static struct _s_x rule_action_params[] = { | ||||
{ "log", TOK_LOG }, | { "log", TOK_LOG }, | ||||
{ "tag", TOK_TAG }, | { "tag", TOK_TAG }, | ||||
{ "untag", TOK_UNTAG }, | { "untag", TOK_UNTAG }, | ||||
{ NULL, 0 } /* terminator */ | { NULL, 0 } /* terminator */ | ||||
}; | }; | ||||
/* | /* | ||||
* The 'lookup' instruction accepts one of the following arguments. | * 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. | * Arguments are passed as v[1] in O_DST_LOOKUP options. | ||||
*/ | */ | ||||
static int lookup_key[] = { | static struct _s_x lookup_keys[] = { | ||||
TOK_DSTIP, TOK_SRCIP, TOK_DSTPORT, TOK_SRCPORT, | { "dst-ip", LOOKUP_DST_IP }, | ||||
TOK_UID, TOK_JAIL, TOK_DSCP, -1 }; | { "src-ip", LOOKUP_SRC_IP }, | ||||
{ "dst-port", LOOKUP_DST_PORT }, | |||||
{ "src-port", LOOKUP_SRC_PORT }, | |||||
{ "dst-mac", LOOKUP_DST_MAC }, | |||||
{ "src-mac", LOOKUP_SRC_MAC }, | |||||
{ "uid", LOOKUP_UID }, | |||||
{ "jail", LOOKUP_JAIL }, | |||||
{ "dscp", LOOKUP_DSCP }, | |||||
{ NULL, 0 }, | |||||
}; | |||||
static struct _s_x rule_options[] = { | static struct _s_x rule_options[] = { | ||||
{ "tagged", TOK_TAGGED }, | { "tagged", TOK_TAGGED }, | ||||
{ "uid", TOK_UID }, | { "uid", TOK_UID }, | ||||
{ "gid", TOK_GID }, | { "gid", TOK_GID }, | ||||
{ "jail", TOK_JAIL }, | { "jail", TOK_JAIL }, | ||||
{ "in", TOK_IN }, | { "in", TOK_IN }, | ||||
{ "limit", TOK_LIMIT }, | { "limit", TOK_LIMIT }, | ||||
Show All 36 Lines | static struct _s_x rule_options[] = { | ||||
{ "tcpack", TOK_TCPACK }, | { "tcpack", TOK_TCPACK }, | ||||
{ "tcpwin", TOK_TCPWIN }, | { "tcpwin", TOK_TCPWIN }, | ||||
{ "icmptype", TOK_ICMPTYPES }, | { "icmptype", TOK_ICMPTYPES }, | ||||
{ "icmptypes", TOK_ICMPTYPES }, | { "icmptypes", TOK_ICMPTYPES }, | ||||
{ "dst-ip", TOK_DSTIP }, | { "dst-ip", TOK_DSTIP }, | ||||
{ "src-ip", TOK_SRCIP }, | { "src-ip", TOK_SRCIP }, | ||||
{ "dst-port", TOK_DSTPORT }, | { "dst-port", TOK_DSTPORT }, | ||||
{ "src-port", TOK_SRCPORT }, | { "src-port", TOK_SRCPORT }, | ||||
{ "dst-mac", TOK_DSTMAC }, | |||||
{ "src-mac", TOK_SRCMAC }, | |||||
{ "proto", TOK_PROTO }, | { "proto", TOK_PROTO }, | ||||
{ "MAC", TOK_MAC }, | { "MAC", TOK_MAC }, | ||||
{ "mac", TOK_MAC }, | { "mac", TOK_MAC }, | ||||
{ "mac-type", TOK_MACTYPE }, | { "mac-type", TOK_MACTYPE }, | ||||
{ "verrevpath", TOK_VERREVPATH }, | { "verrevpath", TOK_VERREVPATH }, | ||||
{ "versrcreach", TOK_VERSRCREACH }, | { "versrcreach", TOK_VERSRCREACH }, | ||||
{ "antispoof", TOK_ANTISPOOF }, | { "antispoof", TOK_ANTISPOOF }, | ||||
{ "ipsec", TOK_IPSEC }, | { "ipsec", TOK_IPSEC }, | ||||
{ "icmp6type", TOK_ICMP6TYPES }, | { "icmp6type", TOK_ICMP6TYPES }, | ||||
{ "icmp6types", TOK_ICMP6TYPES }, | { "icmp6types", TOK_ICMP6TYPES }, | ||||
{ "ext6hdr", TOK_EXT6HDR}, | { "ext6hdr", TOK_EXT6HDR }, | ||||
{ "flow-id", TOK_FLOWID}, | { "flow-id", TOK_FLOWID }, | ||||
{ "ipv6", TOK_IPV6}, | { "ipv6", TOK_IPV6 }, | ||||
{ "ip6", TOK_IPV6}, | { "ip6", TOK_IPV6 }, | ||||
{ "ipv4", TOK_IPV4}, | { "ipv4", TOK_IPV4 }, | ||||
{ "ip4", TOK_IPV4}, | { "ip4", TOK_IPV4 }, | ||||
{ "dst-ipv6", TOK_DSTIP6}, | { "dst-ipv6", TOK_DSTIP6 }, | ||||
{ "dst-ip6", TOK_DSTIP6}, | { "dst-ip6", TOK_DSTIP6 }, | ||||
{ "src-ipv6", TOK_SRCIP6}, | { "src-ipv6", TOK_SRCIP6 }, | ||||
{ "src-ip6", TOK_SRCIP6}, | { "src-ip6", TOK_SRCIP6 }, | ||||
{ "lookup", TOK_LOOKUP}, | { "lookup", TOK_LOOKUP }, | ||||
{ "flow", TOK_FLOW}, | { "flow", TOK_FLOW }, | ||||
{ "defer-action", TOK_SKIPACTION }, | { "defer-action", TOK_SKIPACTION }, | ||||
{ "defer-immediate-action", TOK_SKIPACTION }, | { "defer-immediate-action", TOK_SKIPACTION }, | ||||
{ "//", TOK_COMMENT }, | { "//", TOK_COMMENT }, | ||||
{ "not", TOK_NOT }, /* pseudo option */ | { "not", TOK_NOT }, /* pseudo option */ | ||||
{ "!", /* escape ? */ TOK_NOT }, /* pseudo option */ | { "!", /* escape ? */ TOK_NOT }, /* pseudo option */ | ||||
{ "or", TOK_OR }, /* pseudo option */ | { "or", TOK_OR }, /* pseudo option */ | ||||
{ "|", /* escape */ TOK_OR }, /* pseudo option */ | { "|", /* escape */ TOK_OR }, /* pseudo option */ | ||||
▲ Show 20 Lines • Show All 815 Lines • ▼ Show 20 Lines | print_ip(struct buf_pr *bp, const struct format_opts *fo, | ||||
struct hostent *he = NULL; | struct hostent *he = NULL; | ||||
const struct in_addr *ia; | const struct in_addr *ia; | ||||
const uint32_t *a = ((const ipfw_insn_u32 *)cmd)->d; | const uint32_t *a = ((const ipfw_insn_u32 *)cmd)->d; | ||||
uint32_t len = F_LEN((const ipfw_insn *)cmd); | uint32_t len = F_LEN((const ipfw_insn *)cmd); | ||||
char *t; | char *t; | ||||
bprintf(bp, " "); | bprintf(bp, " "); | ||||
if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) { | if (cmd->o.opcode == O_IP_DST_LOOKUP && len > F_INSN_SIZE(ipfw_insn_u32)) { | ||||
uint32_t d = a[1]; | const char *arg; | ||||
const char *arg = "<invalid>"; | |||||
if (d < sizeof(lookup_key)/sizeof(lookup_key[0])) | arg = match_value(lookup_keys, a[1]); | ||||
arg = match_value(rule_options, lookup_key[d]); | |||||
t = table_search_ctlv(fo->tstate, | t = table_search_ctlv(fo->tstate, | ||||
((const ipfw_insn *)cmd)->arg1); | ((const ipfw_insn *)cmd)->arg1); | ||||
bprintf(bp, "lookup %s %s", arg, t); | bprintf(bp, "lookup %s %s", arg, t); | ||||
return; | return; | ||||
} | } | ||||
if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) { | if (cmd->o.opcode == O_IP_SRC_ME || cmd->o.opcode == O_IP_DST_ME) { | ||||
bprintf(bp, "me"); | bprintf(bp, "me"); | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 100 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
bprintf(bp, " MAC"); | bprintf(bp, " MAC"); | ||||
format_mac(bp, mac->addr, mac->mask); | format_mac(bp, mac->addr, mac->mask); | ||||
format_mac(bp, mac->addr + 6, mac->mask + 6); | format_mac(bp, mac->addr + 6, mac->mask + 6); | ||||
} | } | ||||
static void | static void | ||||
print_mac_lookup(struct buf_pr *bp, const struct format_opts *fo, | |||||
const ipfw_insn *cmd) | |||||
{ | |||||
uint32_t len = F_LEN(cmd); | |||||
char *t; | |||||
bprintf(bp, " "); | |||||
t = table_search_ctlv(fo->tstate, cmd->arg1); | |||||
bprintf(bp, "table(%s", t); | |||||
if (len == F_INSN_SIZE(ipfw_insn_u32)) | |||||
bprintf(bp, ",%u", ((const ipfw_insn_u32 *)cmd)->d[0]); | |||||
bprintf(bp, ")"); | |||||
} | |||||
static void | |||||
fill_icmptypes(ipfw_insn_u32 *cmd, char *av) | fill_icmptypes(ipfw_insn_u32 *cmd, char *av) | ||||
{ | { | ||||
uint8_t type; | uint8_t type; | ||||
cmd->d[0] = 0; | cmd->d[0] = 0; | ||||
while (*av) { | while (*av) { | ||||
if (*av == ',') | if (*av == ',') | ||||
av++; | av++; | ||||
▲ Show 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | case O_IP6_SRC_ME: | ||||
break; | break; | ||||
case O_IP6_DST: | case O_IP6_DST: | ||||
case O_IP6_DST_MASK: | case O_IP6_DST_MASK: | ||||
case O_IP6_DST_ME: | case O_IP6_DST_ME: | ||||
if (state->flags & HAVE_DSTIP) | if (state->flags & HAVE_DSTIP) | ||||
bprintf(bp, " dst-ip6"); | bprintf(bp, " dst-ip6"); | ||||
print_ip6(bp, insntod(cmd, ip6)); | print_ip6(bp, insntod(cmd, ip6)); | ||||
break; | break; | ||||
case O_MAC_SRC_LOOKUP: | |||||
bprintf(bp, " src-mac"); | |||||
print_mac_lookup(bp, fo, cmd); | |||||
break; | |||||
case O_MAC_DST_LOOKUP: | |||||
bprintf(bp, " dst-mac"); | |||||
print_mac_lookup(bp, fo, cmd); | |||||
break; | |||||
case O_FLOW6ID: | case O_FLOW6ID: | ||||
print_flow6id(bp, insntod(cmd, u32)); | print_flow6id(bp, insntod(cmd, u32)); | ||||
break; | break; | ||||
case O_IP_DSTPORT: | case O_IP_DSTPORT: | ||||
case O_IP_SRCPORT: | case O_IP_SRCPORT: | ||||
print_newports(bp, insntod(cmd, u16), state->proto, | print_newports(bp, insntod(cmd, u16), state->proto, | ||||
(state->flags & (HAVE_SRCIP | HAVE_DSTIP)) == | (state->flags & (HAVE_SRCIP | HAVE_DSTIP)) == | ||||
(HAVE_SRCIP | HAVE_DSTIP) ? cmd->opcode: 0); | (HAVE_SRCIP | HAVE_DSTIP) ? cmd->opcode: 0); | ||||
▲ Show 20 Lines • Show All 1,116 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
list_static_range(struct cmdline_opts *co, struct format_opts *fo, | list_static_range(struct cmdline_opts *co, struct format_opts *fo, | ||||
struct buf_pr *bp, ipfw_obj_tlv *rtlv, int rcnt) | struct buf_pr *bp, ipfw_obj_tlv *rtlv, int rcnt) | ||||
{ | { | ||||
int n, seen; | int n, seen; | ||||
struct ip_fw_rule *r; | struct ip_fw_rule *r; | ||||
struct ip_fw_bcounter *cntr; | struct ip_fw_bcounter *cntr; | ||||
int c = 0; | |||||
for (n = seen = 0; n < rcnt; n++, | for (n = seen = 0; n < rcnt; n++, | ||||
rtlv = (ipfw_obj_tlv *)((caddr_t)rtlv + rtlv->length)) { | rtlv = (ipfw_obj_tlv *)((caddr_t)rtlv + rtlv->length)) { | ||||
if ((fo->show_counters | fo->show_time) != 0) { | if ((fo->show_counters | fo->show_time) != 0) { | ||||
cntr = (struct ip_fw_bcounter *)(rtlv + 1); | cntr = (struct ip_fw_bcounter *)(rtlv + 1); | ||||
r = (struct ip_fw_rule *)((caddr_t)cntr + cntr->size); | r = (struct ip_fw_rule *)((caddr_t)cntr + cntr->size); | ||||
} else { | } else { | ||||
cntr = NULL; | cntr = NULL; | ||||
r = (struct ip_fw_rule *)(rtlv + 1); | r = (struct ip_fw_rule *)(rtlv + 1); | ||||
} | } | ||||
if (r->rulenum > fo->last) | if (r->rulenum > fo->last) | ||||
break; | break; | ||||
if (co->use_set && r->set != co->use_set - 1) | if (co->use_set && r->set != co->use_set - 1) | ||||
continue; | continue; | ||||
if (r->rulenum >= fo->first && r->rulenum <= fo->last) { | if (r->rulenum >= fo->first && r->rulenum <= fo->last) { | ||||
show_static_rule(co, fo, bp, r, cntr); | show_static_rule(co, fo, bp, r, cntr); | ||||
printf("%s", bp->buf); | printf("%s", bp->buf); | ||||
c += rtlv->length; | |||||
bp_flush(bp); | bp_flush(bp); | ||||
seen++; | seen++; | ||||
} | } | ||||
} | } | ||||
return (seen); | return (seen); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo, | ||||
size_t dynsz; | size_t dynsz; | ||||
int rcnt; | int rcnt; | ||||
int exitval = EX_OK; | int exitval = EX_OK; | ||||
int lac; | int lac; | ||||
char **lav; | char **lav; | ||||
char *endptr; | char *endptr; | ||||
size_t readsz; | size_t readsz; | ||||
struct buf_pr bp; | struct buf_pr bp; | ||||
ipfw_obj_ctlv *ctlv, *tstate; | ipfw_obj_ctlv *ctlv; | ||||
ipfw_obj_tlv *rbase; | ipfw_obj_tlv *rbase; | ||||
/* | /* | ||||
* Handle tablenames TLV first, if any | * Handle tablenames TLV first, if any | ||||
*/ | */ | ||||
tstate = NULL; | |||||
rbase = NULL; | rbase = NULL; | ||||
dynbase = NULL; | dynbase = NULL; | ||||
dynsz = 0; | dynsz = 0; | ||||
readsz = sizeof(*cfg); | readsz = sizeof(*cfg); | ||||
rcnt = 0; | rcnt = 0; | ||||
fo->set_mask = cfg->set_mask; | fo->set_mask = cfg->set_mask; | ||||
▲ Show 20 Lines • Show All 871 Lines • ▼ Show 20 Lines | else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn)) /* me */ | ||||
cmd->opcode = O_IP_DST_ME; | cmd->opcode = O_IP_DST_ME; | ||||
else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32)) /* one IP */ | else if (F_LEN(cmd) == F_INSN_SIZE(ipfw_insn_u32)) /* one IP */ | ||||
cmd->opcode = O_IP_DST; | cmd->opcode = O_IP_DST; | ||||
else /* addr/mask */ | else /* addr/mask */ | ||||
cmd->opcode = O_IP_DST_MASK; | cmd->opcode = O_IP_DST_MASK; | ||||
return cmd; | return cmd; | ||||
} | } | ||||
static ipfw_insn * | |||||
add_srcmac(ipfw_insn *cmd, char *av, struct tidx *tstate) | |||||
{ | |||||
if (strncmp(av, "table(", 6) == 0) | |||||
fill_table(cmd, av, O_MAC_SRC_LOOKUP, tstate); | |||||
else | |||||
errx(EX_DATAERR, "only mac table lookup is supported %s", av); | |||||
return cmd; | |||||
} | |||||
static ipfw_insn * | |||||
add_dstmac(ipfw_insn *cmd, char *av, struct tidx *tstate) | |||||
{ | |||||
if (strncmp(av, "table(", 6) == 0) | |||||
fill_table(cmd, av, O_MAC_DST_LOOKUP, tstate); | |||||
else | |||||
errx(EX_DATAERR, "only mac table lookup is supported %s", av); | |||||
return cmd; | |||||
} | |||||
static struct _s_x f_reserved_keywords[] = { | static struct _s_x f_reserved_keywords[] = { | ||||
{ "altq", TOK_OR }, | { "altq", TOK_OR }, | ||||
{ "//", TOK_OR }, | { "//", TOK_OR }, | ||||
{ "diverted", TOK_OR }, | { "diverted", TOK_OR }, | ||||
{ "dst-port", TOK_OR }, | { "dst-port", TOK_OR }, | ||||
{ "src-port", TOK_OR }, | { "src-port", TOK_OR }, | ||||
{ "established", TOK_OR }, | { "established", TOK_OR }, | ||||
{ "keep-state", TOK_OR }, | { "keep-state", TOK_OR }, | ||||
▲ Show 20 Lines • Show All 1,214 Lines • ▼ Show 20 Lines | while ( av[0] != NULL ) { | ||||
case TOK_DSTIP6: | case TOK_DSTIP6: | ||||
NEED1("missing destination IP6"); | NEED1("missing destination IP6"); | ||||
if (add_dstip6(cmd, *av, cblen, tstate)) { | if (add_dstip6(cmd, *av, cblen, tstate)) { | ||||
av++; | av++; | ||||
} | } | ||||
break; | break; | ||||
case TOK_SRCMAC: | |||||
NEED1("missing source MAC"); | |||||
if (add_srcmac(cmd, *av, tstate)) { | |||||
av++; | |||||
} | |||||
break; | |||||
case TOK_DSTMAC: | |||||
NEED1("missing destination MAC"); | |||||
if (add_dstmac(cmd, *av, tstate)) { | |||||
av++; | |||||
} | |||||
break; | |||||
case TOK_SRCPORT: | case TOK_SRCPORT: | ||||
NEED1("missing source port"); | NEED1("missing source port"); | ||||
if (_substrcmp(*av, "any") == 0 || | if (_substrcmp(*av, "any") == 0 || | ||||
add_ports(cmd, *av, proto, O_IP_SRCPORT, cblen)) { | add_ports(cmd, *av, proto, O_IP_SRCPORT, cblen)) { | ||||
av++; | av++; | ||||
} else | } else | ||||
errx(EX_DATAERR, "invalid source port %s", *av); | errx(EX_DATAERR, "invalid source port %s", *av); | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | case TOK_FIB: | ||||
av++; | av++; | ||||
break; | break; | ||||
case TOK_SOCKARG: | case TOK_SOCKARG: | ||||
fill_cmd(cmd, O_SOCKARG, 0, 0); | fill_cmd(cmd, O_SOCKARG, 0, 0); | ||||
break; | break; | ||||
case TOK_LOOKUP: { | case TOK_LOOKUP: { | ||||
ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd; | ipfw_insn_u32 *c = (ipfw_insn_u32 *)cmd; | ||||
int j; | |||||
if (!av[0] || !av[1]) | if (!av[0] || !av[1]) | ||||
errx(EX_USAGE, "format: lookup argument tablenum"); | errx(EX_USAGE, "format: lookup argument tablenum"); | ||||
cmd->opcode = O_IP_DST_LOOKUP; | cmd->opcode = O_IP_DST_LOOKUP; | ||||
cmd->len |= F_INSN_SIZE(ipfw_insn) + 2; | cmd->len |= F_INSN_SIZE(ipfw_insn) + 2; | ||||
i = match_token(rule_options, *av); | i = match_token(lookup_keys, *av); | ||||
for (j = 0; lookup_key[j] >= 0 ; j++) { | if (i == -1) | ||||
if (i == lookup_key[j]) | |||||
break; | |||||
} | |||||
if (lookup_key[j] <= 0) | |||||
errx(EX_USAGE, "format: cannot lookup on %s", *av); | errx(EX_USAGE, "format: cannot lookup on %s", *av); | ||||
__PAST_END(c->d, 1) = j; // i converted to option | __PAST_END(c->d, 1) = i; | ||||
av++; | av++; | ||||
if ((j = pack_table(tstate, *av)) == 0) | if ((i = pack_table(tstate, *av)) == 0) | ||||
errx(EX_DATAERR, "Invalid table name: %s", *av); | errx(EX_DATAERR, "Invalid table name: %s", *av); | ||||
cmd->arg1 = j; | cmd->arg1 = i; | ||||
av++; | av++; | ||||
} | } | ||||
break; | break; | ||||
case TOK_FLOW: | case TOK_FLOW: | ||||
NEED1("missing table name"); | NEED1("missing table name"); | ||||
if (strncmp(*av, "table(", 6) != 0) | if (strncmp(*av, "table(", 6) != 0) | ||||
errx(EX_DATAERR, | errx(EX_DATAERR, | ||||
"enclose table name into \"table()\""); | "enclose table name into \"table()\""); | ||||
fill_table(cmd, *av, O_IP_FLOW_LOOKUP, tstate); | fill_table(cmd, *av, O_IP_FLOW_LOOKUP, tstate); | ||||
av++; | av++; | ||||
▲ Show 20 Lines • Show All 615 Lines • Show Last 20 Lines |