From owner-p4-projects@FreeBSD.ORG Wed May 27 19:13:37 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 17739106567A; Wed, 27 May 2009 19:13:37 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C960F1065670 for ; Wed, 27 May 2009 19:13:36 +0000 (UTC) (envelope-from tsel@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id B73668FC1E for ; Wed, 27 May 2009 19:13:36 +0000 (UTC) (envelope-from tsel@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n4RJDaEh070026 for ; Wed, 27 May 2009 19:13:36 GMT (envelope-from tsel@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n4RJDa8r070024 for perforce@freebsd.org; Wed, 27 May 2009 19:13:36 GMT (envelope-from tsel@FreeBSD.org) Date: Wed, 27 May 2009 19:13:36 GMT Message-Id: <200905271913.n4RJDa8r070024@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to tsel@FreeBSD.org using -f From: Tatsiana Elavaya To: Perforce Change Reviews Cc: Subject: PERFORCE change 162900 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 May 2009 19:13:38 -0000 http://perforce.freebsd.org/chv.cgi?CH=162900 Change 162900 by tsel@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] \n\n" "where 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 */ };