--- 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);
