--- ipfw2.c.orig 2008-09-03 10:20:01.000000000 +0800 +++ ipfw2.c 2008-09-03 15:31:34.000000000 +0800 @@ -2721,6 +2721,7 @@ "set [disable N... enable N...] | move [rule] X to Y | swap X Y | show\n" "set N {show|list|zero|resetlog|delete} [N{,N}] | flush\n" "table N {add ip[/bits] [value] | delete ip[/bits] | flush | list}\n" +"table all list\n" "\n" "RULE-BODY: check-state [PARAMS] | ACTION [PARAMS] ADDR [OPTION_LIST]\n" "ACTION: check-state | allow | count | deny | unreach{,6} CODE |\n" @@ -5860,22 +5861,27 @@ * ipfw table N add addr[/masklen] [value] * ipfw table N delete addr[/masklen] * ipfw table N flush - * ipfw table N list + * ipfw table N|all list */ static void table_handler(int ac, char *av[]) { ipfw_table_entry ent; ipfw_table *tbl; - int do_add; + int do_add, is_all = 0; char *p; socklen_t l; - uint32_t a; + uint32_t a, b, c; + size_t len; ac--; av++; if (ac && isdigit(**av)) { ent.tbl = atoi(*av); ac--; av++; + } else if (_substrcmp(*av, "all") == 0) { + ent.tbl = 0; + is_all = 1; + ac--; av++; } else errx(EX_USAGE, "table number required"); NEED1("table needs command"); @@ -5931,33 +5937,48 @@ if (do_cmd(IP_FW_TABLE_FLUSH, &ent.tbl, sizeof(ent.tbl)) < 0) err(EX_OSERR, "setsockopt(IP_FW_TABLE_FLUSH)"); } else if (_substrcmp(*av, "list") == 0) { - a = ent.tbl; - l = sizeof(a); - if (do_cmd(IP_FW_TABLE_GETSIZE, &a, (uintptr_t)&l) < 0) - err(EX_OSERR, "getsockopt(IP_FW_TABLE_GETSIZE)"); - l = sizeof(*tbl) + a * sizeof(ipfw_table_entry); - tbl = malloc(l); - if (tbl == NULL) - err(EX_OSERR, "malloc"); - tbl->tbl = ent.tbl; - if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0) - err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)"); - for (a = 0; a < tbl->cnt; a++) { - unsigned int tval; - tval = tbl->ent[a].value; - if (do_value_as_ip) { - char tbuf[128]; - strncpy(tbuf, inet_ntoa(*(struct in_addr *) - &tbl->ent[a].addr), 127); - /* inet_ntoa expects network order */ - tval = htonl(tval); - printf("%s/%u %s\n", tbuf, tbl->ent[a].masklen, - inet_ntoa(*(struct in_addr *)&tval)); - } else { - printf("%s/%u %u\n", - inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), - tbl->ent[a].masklen, tval); + c = ent.tbl; + if (is_all) { + len = sizeof(uint32_t); + /* get IPFW_TABLES_MAX */ + if (sysctlbyname("net.inet.ip.fw.tables_max", + &c, &len, NULL, 0) == -1) + errx(1, "sysctlbyname(\"%s\")", + "net.inet.ip.fw.tables_max"); + c -= 1; + } + for (b = ent.tbl; b <= c; b++) { + a = b; + l = sizeof(b); + if (do_cmd(IP_FW_TABLE_GETSIZE, &a, (uintptr_t)&l) < 0) + err(EX_OSERR, "getsockopt(IP_FW_TABLE_GETSIZE)"); + l = sizeof(*tbl) + a * sizeof(ipfw_table_entry); + tbl = malloc(l); + if (tbl == NULL) + err(EX_OSERR, "malloc"); + tbl->tbl = b; + if (do_cmd(IP_FW_TABLE_LIST, tbl, (uintptr_t)&l) < 0) + err(EX_OSERR, "getsockopt(IP_FW_TABLE_LIST)"); + if (tbl->cnt && is_all) + printf("---table(%d)---\n", b); + for (a = 0; a < tbl->cnt; a++) { + unsigned int tval; + tval = tbl->ent[a].value; + if (do_value_as_ip) { + char tbuf[128]; + strncpy(tbuf, inet_ntoa(*(struct in_addr *) + &tbl->ent[a].addr), 127); + /* inet_ntoa expects network order */ + tval = htonl(tval); + printf("%s/%u %s\n", tbuf, tbl->ent[a].masklen, + inet_ntoa(*(struct in_addr *)&tval)); + } else { + printf("%s/%u %u\n", + inet_ntoa(*(struct in_addr *)&tbl->ent[a].addr), + tbl->ent[a].masklen, tval); + } } + free(tbl); } } else errx(EX_USAGE, "invalid table command %s", *av);