IPFW_TABLES_MAX in src/sbin/ipfw/ipfw2.c

Ganbold ganbold at micom.mng.net
Mon Sep 1 09:38:58 UTC 2008


Andrey V. Elsukov wrote:
> Ganbold wrote:
>> Hi,
>>
>> Sorry for sending this third time (2 to freebsd-ipfw, 1 to freebsd-net).
>>
>> I'm trying to make small changes in ipfw2.c code (RELENG_7), but make 
>> fails with following error:
>>
>> v02# make
>> cc -O2 -fno-strict-aliasing -pipe  -Wno-pointer-sign -c
>> /usr/src/sbin/ipfw/ipfw2.c
>> /usr/src/sbin/ipfw/ipfw2.c: In function 'table_handler':
>> /usr/src/sbin/ipfw/ipfw2.c:5941: error: 'IPFW_TABLES_MAX' undeclared
>> (first use in this function)
>> /usr/src/sbin/ipfw/ipfw2.c:5941: error: (Each undeclared identifier is
>> reported only once
>> /usr/src/sbin/ipfw/ipfw2.c:5941: error: for each function it appears 
>> in.)
>> *** Error code 1
>>
>> IPFW_TABLES_MAX seems like defined in netinet/ip_fw.h, which is included
>> in ipfw2.c:
>>
>
> IPFW_TABLES_MAX protected by _KERNEL macro. This is why you get
> an error.
Yeah, my fault, I was looking around IPFW_INTERNAL and missed _KERNEL macro.
I defined new sysctl variable in netinet/ip_fw2.c and now I'm able to 
get IPFW_TABLES_MAX via sysctl from /sbin/ipfw.
Is it the way I should get constant protected by _KERNEL?

Also should I PR my patch?

Anyway here is the diff against RELENG_7. Please let me know if I'm 
doing something wrong here.

-------------------------------------------------------------------
--- ip_fw2.c.orig    2008-09-01 17:31:57.000000000 +0800
+++ ip_fw2.c    2008-09-01 16:54:30.000000000 +0800
@@ -255,6 +255,8 @@
 static u_int32_t dyn_count;        /* # of dynamic rules */
 static u_int32_t dyn_max = 4096;    /* max # of dynamic rules */
 
+static u_int32_t tables_count = IPFW_TABLES_MAX;    /* # of tables */
+
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLFLAG_RW,
     &dyn_buckets, 0, "Number of dyn. buckets");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLFLAG_RD,
@@ -265,6 +267,8 @@
     &dyn_max, 0, "Max number of dyn. rules");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, static_count, CTLFLAG_RD,
     &static_count, 0, "Number of static rules");
+SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, tables_count, CTLFLAG_RD,
+    &tables_count, 0, "Number of tables");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLFLAG_RW,
     &dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLFLAG_RW,

-------------------------------------------------------------------
--- /usr/src/sbin/ipfw/ipfw2.c    2008-07-31 09:39:59.000000000 +0800
+++ ipfw2.c    2008-09-01 16:46:08.000000000 +0800
@@ -5860,24 +5860,30 @@
  *     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");
     if (_substrcmp(*av, "add") == 0 ||
         _substrcmp(*av, "delete") == 0) {
@@ -5931,33 +5937,55 @@
         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_count",
+                            &c, &len, NULL, 0) == -1)
+                        errx(1, "sysctlbyname(\"%s\")",
+                            "net.inet.ip.fw.tables_count");
+
+            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);


thanks,

Ganbold




-- 
Life is a grand adventure -- or it is nothing. -- Helen Keller


More information about the freebsd-net mailing list