Most Linux distributions have IP forwarding disabled and it gets me every time. The FORWARD chain is pretty much useless with forwarding disabled, so make ip{,6}tables -L print a message notifying the user instead of actually listing the contents. Jethro Beekman
--- a/iptables/ip6tables.c 2014-06-28 00:20:35.845014216 -0700 +++ b/iptables/ip6tables.c 2014-06-28 00:21:46.729015280 -0700 @@ -42,6 +42,7 @@ #include <fcntl.h> #include <sys/types.h> #include <sys/socket.h> +#include <glob.h> #include "ip6tables-multi.h" #include "xshared.h" @@ -888,6 +889,40 @@ return ip6tc_delete_chain(chain, handle); } +static int is_forwarding_enabled(void) +{ + glob_t globbuf; + int opened_any=0,forwarding_enabled=0; + + if (glob("/proc/sys/net/ipv6/conf/*/forwarding",GLOB_NOSORT,NULL,&globbuf)==0) + { + size_t n; + for (n=0;n<globbuf.gl_pathc;n++) + { + if (strncmp(globbuf.gl_pathv[n],"/proc/sys/net/ipv6/conf/",24)==0 && (strncmp(globbuf.gl_pathv[n]+24,"all/",4)==0 || strncmp(globbuf.gl_pathv[n]+24,"default/",8)==0)) + continue; + FILE* fp=fopen(globbuf.gl_pathv[n],"r"); + if (fp) + { + int c=fgetc(fp); + if (c!=EOF) + { + opened_any=1; + forwarding_enabled|=c-'0'; + } + fclose(fp); + } + } + + globfree(&globbuf); + } + + if (opened_any==0) + forwarding_enabled=1; + + return forwarding_enabled; +} + static int list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric, int expanded, int linenumbers, struct xtc_handle *handle) @@ -916,6 +951,7 @@ this = ip6tc_next_chain(handle)) { const struct ip6t_entry *i; unsigned int num; + int hide_forward = 0; if (chain && strcmp(chain, this) != 0) continue; @@ -923,7 +959,18 @@ if (found) printf("\n"); if (!rulenum) - print_header(format, this, handle); + { + if (!is_forwarding_enabled() && 0==strcmp("FORWARD", this)) + hide_forward = 1; + if (hide_forward) + { + printf("WARNING: Hiding chain FORWARD because no interfaces have IP forwarding enabled.\n"); + found=1; + continue; + } + else + print_header(format, this, handle); + } i = ip6tc_first_rule(this, handle); num = 0;
--- a/iptables/iptables.c 2013-03-03 13:40:11.000000000 -0800 +++ b/iptables/iptables.c 2014-06-27 17:20:47.109648316 -0700 @@ -39,6 +39,7 @@ #include <iptables.h> #include <xtables.h> #include <fcntl.h> +#include <glob.h> #include "xshared.h" #ifndef TRUE @@ -871,6 +874,40 @@ return iptc_delete_chain(chain, handle); } +static int is_forwarding_enabled(void) +{ + glob_t globbuf; + int opened_any=0,forwarding_enabled=0; + + if (glob("/proc/sys/net/ipv4/conf/*/forwarding",GLOB_NOSORT,NULL,&globbuf)==0) + { + size_t n; + for (n=0;n<globbuf.gl_pathc;n++) + { + if (strncmp(globbuf.gl_pathv[n],"/proc/sys/net/ipv4/conf/",24)==0 && (strncmp(globbuf.gl_pathv[n]+24,"all/",4)==0 || strncmp(globbuf.gl_pathv[n]+24,"default/",8)==0)) + continue; + FILE* fp=fopen(globbuf.gl_pathv[n],"r"); + if (fp) + { + int c=fgetc(fp); + if (c!=EOF) + { + opened_any=1; + forwarding_enabled|=c-'0'; + } + fclose(fp); + } + } + + globfree(&globbuf); + } + + if (opened_any==0) + forwarding_enabled=1; + + return forwarding_enabled; +} + static int list_entries(const xt_chainlabel chain, int rulenum, int verbose, int numeric, int expanded, int linenumbers, struct xtc_handle *handle) @@ -899,6 +936,7 @@ this = iptc_next_chain(handle)) { const struct ipt_entry *i; unsigned int num; + int hide_forward = 0; if (chain && strcmp(chain, this) != 0) continue; @@ -906,7 +944,18 @@ if (found) printf("\n"); if (!rulenum) - print_header(format, this, handle); + { + if (!is_forwarding_enabled() && 0==strcmp("FORWARD", this)) + hide_forward = 1; + if (hide_forward) + { + printf("WARNING: Hiding chain FORWARD because no interfaces have IP forwarding enabled.\n"); + found=1; + continue; + } + else + print_header(format, this, handle); + } i = iptc_first_rule(this, handle); num = 0;