static int fg_iptables_common(struct filter *filter, int flags, sa_family_t family, const char *iptables) { long feat = 0; int r = 0; struct fg_misc misc = { flags, &feat }; fg_callback cb_iptables = { rule: family == AF_INET ? cb_iptables_rule : cb_ip6tables_rule, group: family == AF_INET ? cb_iptables_group : cb_ip6tables_group, }; const int nchains = 3; filter_unroll(&filter); filter_apply_flags(filter, flags); if(!(flags & FF_NOSKEL)) { oputs("CHAINS=\"INPUT OUTPUT FORWARD\""); oputs(""); oputs("# Flush/remove rules, set policy"); oprintf("for f in $CHAINS; do %s -P $f DROP; done\n", iptables); oprintf("%s -F; %s -X\n", iptables, iptables); if (family == AF_INET) oprintf("%s -t nat -F; %s -t nat -X\n", iptables, iptables); oputs(""); oputs("# Create FORW_OUT chain"); oprintf("%s -N FORW_OUT\n", iptables); oputs(""); oputs("# Setup INVALID chain"); oprintf("%s -N INVALID\n", iptables); #if 0 oprintf("%s -A INVALID -j LOG --log-prefix \"invalid \"\n", iptables); #endif oprintf("%s -A INVALID -j DROP\n", iptables); oprintf("for f in $CHAINS; do\n" "\t%s -I $f -m state --state INVALID -j INVALID;\n" "done\n", iptables); oputs(""); r += nchains; } if((r = filtergen_cprod(filter, &cb_iptables, &misc)) < 0) return r; if(!(flags & FF_NOSKEL)) { if((flags & FF_LSTATE) && (feat & (A_TCP|A_UDP))) { oputs("for f in $CHAINS; do"); if(feat & A_TCP) { r += nchains; oprintf("\t%s -I $f -p tcp ! --syn -m state --state ESTABLISHED -j ACCEPT;\n", iptables); } if(feat & A_UDP) { r += nchains; oprintf("\t%s -I $f -p udp -m state --state ESTABLISHED -j ACCEPT;\n", iptables); } oputs("done"); } #if 0 oprintf("for f in $CHAINS; do %s -A $f -j LOG; done\n", iptables); r += nchains; #endif } return r; } int fg_iptables(struct filter *filter, int flags) { return fg_iptables_common(filter, flags, AF_INET, IPTABLES); } int fg_ip6tables(struct filter *filter, int flags) { return fg_iptables_common(filter, flags, AF_INET6, IP6TABLES); } /* Rules which just flush the packet filter */ static int flush_iptables_common(enum filtertype policy, sa_family_t family, const char *iptables) { char * ostr; oputs("CHAINS=\"INPUT OUTPUT FORWARD\""); oputs(""); switch (policy) { case T_ACCEPT: ostr = strdup("ACCEPT"); break; case DROP: ostr = strdup("DROP"); break; case T_REJECT: ostr = strdup("REJECT"); break; default: fprintf(stderr, "invalid filtertype %d\n", policy); abort(); } oprintf("for f in $CHAINS; do %s -P $f %s; done\n", iptables, ostr); oprintf("%s -F; %s -X\n", iptables, iptables); if (family == AF_INET) oprintf("%s -t nat -F; %s -t nat -X\n", iptables, iptables); return 0; }
int fg_iptablesrestore(struct filter *filter, int flags) { long feat = 0; int r = 0; struct fg_misc misc = {flags, &feat}; fg_callback cb_iptablesrestore = { .rule = cb_iptablesrestore_rule, .group = cb_iptablesrestore_group, }; const int nchains = 3; filter_unroll(&filter); if (!(flags & FF_NOSKEL)) { /* Add the nat table headers to the llist, to be * followed up by optional real rules */ addnode("*nat"); addnode(":PREROUTING ACCEPT [0:0]"); addnode(":POSTROUTING ACCEPT [0:0]"); addnode(":OUTPUT ACCEPT [0:0]"); /* No COMMIT, that is done after rule output */ oputs("*filter"); oputs(":FORW_OUT - [0:0]"); oputs(":INPUT DROP [0:0]"); oputs(":FORWARD DROP [0:0]"); oputs(":INVALID - [0:0]"); oputs(":OUTPUT DROP [0:0]"); #if 0 oputs("-A INVALID -j LOG --log-prefix \"invalid \""); #endif oputs("-A INVALID -j DROP"); oputs("-A INPUT -m state --state INVALID -j INVALID"); oputs("-A OUTPUT -m state --state INVALID -j INVALID"); oputs("-A FORWARD -m state --state INVALID -j INVALID"); r += nchains; } if ((r = filtergen_cprod(filter, &cb_iptablesrestore, &misc)) < 0) return r; if (!(flags & FF_NOSKEL)) { if ((flags & FF_LSTATE) && (feat & (A_TCP | A_UDP))) { if (feat & A_TCP) { r += nchains; oputs("-I INPUT -p tcp ! --syn -m state --state ESTABLISHED -j ACCEPT"); oputs( "-I OUTPUT -p tcp ! --syn -m state --state ESTABLISHED -j ACCEPT"); oputs( "-I FORWARD -p tcp ! --syn -m state --state ESTABLISHED -j ACCEPT"); } if (feat & A_UDP) { r += nchains; oputs("-I INPUT -p udp -m state --state ESTABLISHED -j ACCEPT"); oputs("-I OUTPUT -p udp -m state --state ESTABLISHED -j ACCEPT"); oputs("-I FORWARD -p udp -m state --state ESTABLISHED -j ACCEPT"); } } #if 0 oputs("-A INPUT -j LOG"); oputs("-A OUTPUT -j LOG"); oputs("-A FORWARD -j LOG"); r += nchains; #endif } oputs("COMMIT"); /* Dump contents of the llist which contains the NAT tabl rules */ for (curr = head; curr != NULL; curr = curr->next) oputs(curr->data); oputs("COMMIT"); freelist(); return r; }