PERFORCE change 162900 for review
Tatsiana Elavaya
tsel at FreeBSD.org
Wed May 27 19:13:38 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=162900
Change 162900 by tsel at tsel_mz on 2009/05/27 19:12:53
Implement rule aliases.
Usage:
# ./ipfw add 200 alias alias2 allow all from any to any
00200 alias alias2 allow ip from any to any
# ./ipfw add 100 alias alias1 skipto alias2 all from any to any
00100 alias alias1 skipto alias2 ip from any to any
# ./ipfw show
00100 18 1152 alias alias1 skipto alias2 ip from any to any
00200 585 117328 alias alias2 allow ip from any to any
65535 109 27557 deny ip from any to any
Affected files ...
.. //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.c#2 edit
.. //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.h#2 edit
.. //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/main.c#2 edit
.. //depot/projects/soc2009/tsel_ipfw/sys/netinet/ip_fw.h#2 edit
Differences ...
==== //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.c#2 (text+ko) ====
@@ -449,6 +449,69 @@
return 0;
}
+static void*
+ipfw_get_all(int ocmd, int *nbytes)
+{
+ void *data = NULL;
+ int nalloc = 1024; /* start somewhere... */
+
+ /* get rules or pipes from kernel, resizing array as necessary */
+ *nbytes = nalloc;
+
+ while (*nbytes >= nalloc) {
+ nalloc = nalloc * 2 + 200;
+ *nbytes = nalloc;
+ data = safe_realloc(data, *nbytes);
+ if (do_cmd(ocmd, data, (uintptr_t)nbytes) < 0)
+ err(EX_OSERR, "getsockopt(IP_%s_GET)",
+ co.do_pipe ? "DUMMYNET" : "FW");
+ }
+ return data;
+}
+
+static struct ip_fw*
+get_rule_cache(int *len)
+{
+ static struct ip_fw *rules = NULL;
+ static int rules_len = 0;
+
+ if (rules == NULL) {
+ rules = (struct ip_fw*) ipfw_get_all(IP_FW_GET, &rules_len);
+ rules_len = rules_len / sizeof(struct ip_fw);
+ }
+
+ *len = rules_len;
+ return rules;
+}
+
+static int
+alias_lookup_rulenum(const char *alias)
+{
+ struct ip_fw *rules;
+ int len, i;
+
+ rules = get_rule_cache(&len);
+ for (i = 0; i < len; i++) {
+ if (!strcmp(rules[i].alias, alias))
+ return rules[i].rulenum;
+ }
+ return -1;
+}
+
+static char*
+alias_lookup(int rulenum)
+{
+ struct ip_fw *rules;
+ int len, i;
+
+ rules = get_rule_cache(&len);
+ for (i = 0; i < len; i++) {
+ if (rules[i].rulenum == rulenum)
+ return rules[i].alias[0] ? rules[i].alias : NULL;
+ }
+ return NULL;
+}
+
/*
* prints one port, symbolic or numeric
*/
@@ -973,6 +1036,9 @@
}
}
+ if (rule->alias[0])
+ printf("alias %s ", rule->alias);
+
if (co.show_sets)
printf("set %d ", rule->set);
@@ -1029,9 +1095,14 @@
print_unreach6_code(cmd->arg1);
break;
- case O_SKIPTO:
- PRINT_UINT_ARG("skipto ", cmd->arg1);
+ case O_SKIPTO: {
+ char *alias = alias_lookup(cmd->arg1);
+ if (alias == NULL)
+ PRINT_UINT_ARG("skipto ", cmd->arg1);
+ else
+ printf("skipto %s", alias);
break;
+ }
case O_PIPE:
PRINT_UINT_ARG("pipe ", cmd->arg1);
@@ -1715,6 +1786,20 @@
}
}
+static void
+ipfw_list_aliases(void *data, uint nbytes, int ac, char *av[])
+{
+ struct ip_fw *rules;
+ int len, i;
+
+ rules = (struct ip_fw*) data;
+ len = nbytes / sizeof(struct ip_fw);
+ for (i = 0; i < len; i++) {
+ if (rules[i].alias[0] != '\0')
+ printf("%-5d %s\n", rules[i].rulenum, rules[i].alias);
+ }
+}
+
void
ipfw_list(int ac, char *av[], int show_counters)
{
@@ -1723,19 +1808,16 @@
#define NEXT(r) ((struct ip_fw *)((char *)r + RULESIZE(r)))
char *lim;
- void *data = NULL;
int bcwidth, n, nbytes, nstat, ndyn, pcwidth, width;
int exitval = EX_OK;
int lac;
char **lav;
+ void *data;
u_long rnum, last;
char *endptr;
int seen = 0;
uint8_t set;
- const int ocmd = co.do_pipe ? IP_DUMMYNET_GET : IP_FW_GET;
- int nalloc = 1024; /* start somewhere... */
-
last = 0;
if (co.test_only) {
@@ -1746,20 +1828,16 @@
ac--;
av++;
- /* get rules or pipes from kernel, resizing array as necessary */
- nbytes = nalloc;
+ data = ipfw_get_all(co.do_pipe ? IP_DUMMYNET_GET : IP_FW_GET, &nbytes);
- while (nbytes >= nalloc) {
- nalloc = nalloc * 2 + 200;
- nbytes = nalloc;
- data = safe_realloc(data, nbytes);
- if (do_cmd(ocmd, data, (uintptr_t)&nbytes) < 0)
- err(EX_OSERR, "getsockopt(IP_%s_GET)",
- co.do_pipe ? "DUMMYNET" : "FW");
+ if (co.do_pipe) {
+ ipfw_list_pipes(data, nbytes, ac, av);
+ goto done;
}
- if (co.do_pipe) {
- ipfw_list_pipes(data, nbytes, ac, av);
+ if (ac && !strcmp(*av, "alias")) {
+ ipfw_list_aliases(data, nbytes, ac, av);
+ ac--; av++;
goto done;
}
@@ -2610,6 +2688,18 @@
ac--;
}
+ /* [alias ALIAS] */
+ if (ac > 1 && _substrcmp(*av, "alias") == 0) {
+ int alias_rule;
+
+ NEED1("missing alias name");
+ alias_rule = alias_lookup_rulenum(av[1]);
+ if (alias_rule > 0)
+ errx(EX_DATAERR, "rule %d already has alias %s", alias_rule, av[1]);
+ strlcpy(rule->alias, av[1], IPFW_ALIAS_NAME_SIZE);
+ av += 2; ac -= 2;
+ }
+
/* [set N] -- set number (0..RESVD_SET), optional */
if (ac > 1 && _substrcmp(*av, "set") == 0) {
int set = strtoul(av[1], NULL, 10);
@@ -2724,6 +2814,11 @@
action->arg1 = ntohs(s->s_port);
else
errx(EX_DATAERR, "illegal divert/tee port");
+ } else if (i == TOK_SKIPTO) {
+ action->arg1 = alias_lookup_rulenum(*av);
+ if (action->arg1 <= 0 || action->arg1 >= IPFW_DEFAULT_RULE)
+ errx(EX_DATAERR, "illegal argument for %s",
+ *(av - 1));
} else
errx(EX_DATAERR, "illegal argument for %s", *(av - 1));
ac--; av++;
==== //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/ipfw2.h#2 (text+ko) ====
==== //depot/projects/soc2009/tsel_ipfw/sbin/ipfw/main.c#2 (text+ko) ====
@@ -40,7 +40,7 @@
"ipfw syntax summary (but please do read the ipfw(8) manpage):\n\n"
"\tipfw [-abcdefhnNqStTv] <command>\n\n"
"where <command> is one of the following:\n\n"
-"add [num] [set N] [prob x] RULE-BODY\n"
+"add [num] [alias ALIAS] [set N] [prob x] RULE-BODY\n"
"{pipe|queue} N config PIPE-BODY\n"
"[pipe|queue] {zero|delete|show} [N{,N}]\n"
"nat N config {ip IPADDR|if IFNAME|log|deny_in|same_ports|unreg_only|reset|\n"
==== //depot/projects/soc2009/tsel_ipfw/sys/netinet/ip_fw.h#2 (text+ko) ====
@@ -421,6 +421,8 @@
*/
} ipfw_insn_icmp6;
+#define IPFW_ALIAS_NAME_SIZE 32
+
/*
* Here we have the structure representing an ipfw rule.
*
@@ -464,6 +466,7 @@
u_int64_t pcnt; /* Packet counter */
u_int64_t bcnt; /* Byte counter */
u_int32_t timestamp; /* tv_sec of last match */
+ char alias[IPFW_ALIAS_NAME_SIZE];
ipfw_insn cmd[1]; /* storage for commands */
};
More information about the p4-projects
mailing list