Enable kernel-side rule filtering based on user request.
Make do_get3() function return real error.
This commit is contained in:
parent
563b5ab132
commit
2aa75134b7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/ipfw/; revision=268016
@ -61,9 +61,10 @@ struct format_opts {
|
||||
int bcwidth;
|
||||
int pcwidth;
|
||||
int show_counters;
|
||||
int first;
|
||||
int last;
|
||||
ipfw_obj_ctlv *tstate;
|
||||
uint32_t flags; /* request flags */
|
||||
uint32_t first; /* first rule to request */
|
||||
uint32_t last; /* last rule to request */
|
||||
ipfw_obj_ctlv *tstate; /* table state data */
|
||||
};
|
||||
|
||||
int resvd_set_number = RESVD_SET;
|
||||
@ -375,7 +376,7 @@ static struct _s_x rule_options[] = {
|
||||
};
|
||||
|
||||
void bprint_uint_arg(struct buf_pr *bp, const char *str, uint32_t arg);
|
||||
static int ipfw_get_config(struct cmdline_opts *co, uint32_t flags,
|
||||
static int ipfw_get_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
ipfw_cfg_lheader **pcfg, size_t *psize);
|
||||
static int ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
ipfw_cfg_lheader *cfg, size_t sz, int ac, char **av);
|
||||
@ -593,6 +594,11 @@ do_get3(int optname, ip_fw3_opheader *op3, size_t *optlen)
|
||||
error = getsockopt(ipfw_socket, IPPROTO_IP, IP_FW3, op3,
|
||||
(socklen_t *)optlen);
|
||||
|
||||
if (error == -1) {
|
||||
if (errno != 0)
|
||||
error = errno;
|
||||
}
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2197,11 +2203,11 @@ prepare_format_opts(struct cmdline_opts *co, struct format_opts *fo,
|
||||
|
||||
static int
|
||||
ipfw_list_static_range(struct cmdline_opts *co, struct format_opts *fo,
|
||||
struct buf_pr *bp, struct ip_fw *r, int nstat)
|
||||
struct buf_pr *bp, struct ip_fw *r, int rcnt)
|
||||
{
|
||||
int n, seen;
|
||||
|
||||
for (n = seen = 0; n < nstat; n++, r = NEXT(r) ) {
|
||||
for (n = seen = 0; n < rcnt; n++, r = NEXT(r) ) {
|
||||
if (r->rulenum > fo->last)
|
||||
break;
|
||||
if (co->use_set && r->set != co->use_set - 1)
|
||||
@ -2218,27 +2224,31 @@ ipfw_list_static_range(struct cmdline_opts *co, struct format_opts *fo,
|
||||
|
||||
static void
|
||||
ipfw_list_dyn_range(struct cmdline_opts *co, struct format_opts *fo,
|
||||
struct buf_pr *bp, ipfw_dyn_rule *d, int ndyn)
|
||||
struct buf_pr *bp, ipfw_dyn_rule *d, int dcnt, int objsize)
|
||||
{
|
||||
int n;
|
||||
uint8_t set;
|
||||
uint16_t rulenum;
|
||||
|
||||
for (n = 0; n < ndyn; n++, d++) {
|
||||
for (n = 0; n < dcnt; n++) {
|
||||
bcopy(&d->rule, &rulenum, sizeof(rulenum));
|
||||
if (rulenum > fo->last)
|
||||
break;
|
||||
if (co->use_set) {
|
||||
bcopy((char *)&d->rule + sizeof(uint16_t),
|
||||
&set, sizeof(uint8_t));
|
||||
if (set != co->use_set - 1)
|
||||
if (set != co->use_set - 1) {
|
||||
d = (ipfw_dyn_rule *)((caddr_t)d + objsize);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (rulenum >= fo->first) {
|
||||
show_dyn_state(co, fo, bp, d);
|
||||
printf("%s\n", bp->buf);
|
||||
bp_flush(bp);
|
||||
}
|
||||
|
||||
d = (ipfw_dyn_rule *)((caddr_t)d + objsize);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2249,7 +2259,10 @@ ipfw_list(int ac, char *av[], int show_counters)
|
||||
struct format_opts sfo;
|
||||
size_t sz;
|
||||
int error;
|
||||
uint32_t flags;
|
||||
int lac;
|
||||
char **lav;
|
||||
uint32_t rnum;
|
||||
char *endptr;
|
||||
|
||||
if (co.test_only) {
|
||||
fprintf(stderr, "Testing only, list disabled\n");
|
||||
@ -2262,16 +2275,30 @@ ipfw_list(int ac, char *av[], int show_counters)
|
||||
|
||||
ac--;
|
||||
av++;
|
||||
memset(&sfo, 0, sizeof(sfo));
|
||||
|
||||
/* Determine rule range to request */
|
||||
if (ac > 0) {
|
||||
for (lac = ac, lav = av; lac != 0; lac--) {
|
||||
rnum = strtoul(*lav++, &endptr, 10);
|
||||
if (sfo.first == 0 || rnum < sfo.first)
|
||||
sfo.first = rnum;
|
||||
|
||||
if (*endptr == '-')
|
||||
rnum = strtoul(endptr + 1, &endptr, 10);
|
||||
if (sfo.last == 0 || rnum > sfo.last)
|
||||
sfo.last = rnum;
|
||||
}
|
||||
}
|
||||
|
||||
/* get configuraion from kernel */
|
||||
cfg = NULL;
|
||||
flags = IPFW_CFG_GET_STATIC;
|
||||
sfo.flags = IPFW_CFG_GET_STATIC;
|
||||
if (co.do_dynamic != 0)
|
||||
flags |= IPFW_CFG_GET_STATES;
|
||||
if ((error = ipfw_get_config(&co, flags, &cfg, &sz)) != 0)
|
||||
sfo.flags |= IPFW_CFG_GET_STATES;
|
||||
if ((error = ipfw_get_config(&co, &sfo, &cfg, &sz)) != 0)
|
||||
err(EX_OSERR, "retrieving config failed");
|
||||
|
||||
memset(&sfo, 0, sizeof(sfo));
|
||||
sfo.show_counters = show_counters;
|
||||
error = ipfw_show_config(&co, &sfo, cfg, sz, ac, av);
|
||||
|
||||
@ -2292,9 +2319,8 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
int exitval = EX_OK;
|
||||
int lac;
|
||||
char **lav;
|
||||
u_long rnum;
|
||||
char *endptr;
|
||||
size_t read;
|
||||
size_t dobjsz, read;
|
||||
struct buf_pr bp;
|
||||
ipfw_obj_ctlv *ctlv, *tstate;
|
||||
|
||||
@ -2304,6 +2330,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
tstate = NULL;
|
||||
rbase = NULL;
|
||||
dynbase = NULL;
|
||||
dobjsz = 0;
|
||||
read = 0;
|
||||
|
||||
ctlv = (ipfw_obj_ctlv *)(cfg + 1);
|
||||
@ -2329,7 +2356,8 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
if ((cfg->flags & IPFW_CFG_GET_STATES) && (read != sz)) {
|
||||
/* We may have some dynamic rules */
|
||||
read += sizeof(ipfw_obj_ctlv);
|
||||
dcnt = ((sz - read) / ctlv->objsize);
|
||||
dobjsz = ctlv->objsize;
|
||||
dcnt = (sz - read) / dobjsz;
|
||||
if (dcnt != 0)
|
||||
dynbase = (ipfw_dyn_rule *)(ctlv + 1);
|
||||
}
|
||||
@ -2345,7 +2373,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
|
||||
if (co->do_dynamic && dcnt) {
|
||||
printf("## Dynamic rules (%d):\n", dcnt);
|
||||
ipfw_list_dyn_range(co, fo, &bp, dynbase, dcnt);
|
||||
ipfw_list_dyn_range(co, fo, &bp, dynbase, dcnt, dobjsz);
|
||||
}
|
||||
|
||||
bp_free(&bp);
|
||||
@ -2368,7 +2396,11 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
/* give precedence to other error(s) */
|
||||
if (exitval == EX_OK)
|
||||
exitval = EX_UNAVAILABLE;
|
||||
warnx("rule %lu does not exist", rnum);
|
||||
if (fo->first == fo->last)
|
||||
warnx("rule %u does not exist", fo->first);
|
||||
else
|
||||
warnx("no rules in range %u-%u",
|
||||
fo->first, fo->last);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2381,7 +2413,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
if (*endptr)
|
||||
/* already warned */
|
||||
continue;
|
||||
ipfw_list_dyn_range(co, fo, &bp, dynbase, dcnt);
|
||||
ipfw_list_dyn_range(co, fo, &bp, dynbase, dcnt, dobjsz);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2400,7 +2432,7 @@ ipfw_show_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
*/
|
||||
|
||||
static int
|
||||
ipfw_get_config(struct cmdline_opts *co, uint32_t flags,
|
||||
ipfw_get_config(struct cmdline_opts *co, struct format_opts *fo,
|
||||
ipfw_cfg_lheader **pcfg, size_t *psize)
|
||||
{
|
||||
ipfw_cfg_lheader *cfg;
|
||||
@ -2423,9 +2455,11 @@ ipfw_get_config(struct cmdline_opts *co, uint32_t flags,
|
||||
if ((cfg = calloc(1, sz)) == NULL)
|
||||
return (ENOMEM);
|
||||
|
||||
cfg->flags = flags;
|
||||
cfg->flags = fo->flags;
|
||||
cfg->start_rule = fo->first;
|
||||
cfg->end_rule = fo->last;
|
||||
|
||||
if (do_get3(IP_FW_XGET, &cfg->opheader, &sz) < 0) {
|
||||
if ((error = do_get3(IP_FW_XGET, &cfg->opheader, &sz)) != 0) {
|
||||
if (error != ENOMEM) {
|
||||
free(cfg);
|
||||
return (error);
|
||||
|
@ -1087,7 +1087,7 @@ dump_config(struct ip_fw_chain *chain, struct sockopt_data *sd)
|
||||
{
|
||||
ipfw_cfg_lheader *hdr;
|
||||
struct ip_fw *rule;
|
||||
uint32_t sz;
|
||||
uint32_t sz, rnum;
|
||||
int error, i;
|
||||
struct dump_args da;
|
||||
uint32_t *bmask;
|
||||
@ -1114,6 +1114,16 @@ dump_config(struct ip_fw_chain *chain, struct sockopt_data *sd)
|
||||
da.b = 0;
|
||||
da.e = chain->n_rules;
|
||||
|
||||
if (hdr->end_rule != 0) {
|
||||
/* Handle custom range */
|
||||
if ((rnum = hdr->start_rule) > IPFW_DEFAULT_RULE)
|
||||
rnum = IPFW_DEFAULT_RULE;
|
||||
da.b = ipfw_find_rule(chain, rnum, 0);
|
||||
rnum = hdr->end_rule;
|
||||
rnum = (rnum < IPFW_DEFAULT_RULE) ? rnum+1 : IPFW_DEFAULT_RULE;
|
||||
da.e = ipfw_find_rule(chain, rnum, 0);
|
||||
}
|
||||
|
||||
if (hdr->flags & IPFW_CFG_GET_STATIC) {
|
||||
for (i = da.b; i < da.e; i++) {
|
||||
rule = chain->map[i];
|
||||
|
Loading…
Reference in New Issue
Block a user