static int do_output(const char *tablename) { struct xtc_handle *h; const char *chain = NULL; if (!tablename) return for_each_table(&do_output); h = iptc_init(tablename); if (h == NULL) { xtables_load_ko(xtables_modprobe_program, false); h = iptc_init(tablename); } if (!h) xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n", iptc_strerror(errno)); time_t now = time(NULL); printf("# Generated by iptables-save v%s on %s", IPTABLES_VERSION, ctime(&now)); printf("*%s\n", tablename); /* Dump out chain names first, * thereby preventing dependency conflicts */ for (chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h)) { printf(":%s ", chain); if (iptc_builtin(chain, h)) { struct xt_counters count; printf("%s ", iptc_get_policy(chain, &count, h)); printf("[%llu:%llu]\n", (unsigned long long)count.pcnt, (unsigned long long)count.bcnt); } else { printf("- [0:0]\n"); } } for (chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h)) { const struct ipt_entry *e; /* Dump out rules */ e = iptc_first_rule(chain, h); while(e) { print_rule4(e, h, chain, show_counters); e = iptc_next_rule(e, h); } } now = time(NULL); printf("COMMIT\n"); printf("# Completed on %s", ctime(&now)); iptc_free(h); return 1; }
// Recursive delete of all iptables chains. static int __lua_iptc_flush_all_chains(lua_State *L) { int i, r; const char *chain; const char *table = luaL_checkstring(L, 1); i = find_table(table); if(i == -1) return eprintf("Invalid table: %s", table); if(!tables[i].handle) return eprintf("Invalid table: %s", table); chain = iptc_first_chain(tables[i].handle); while(chain) { r = iptc_flush_entries(chain, tables[i].handle); if(!r) return eprintf("Unable to flush chain: %s: %s", table, chain); chain = iptc_next_chain(tables[i].handle); } return 0; }
//TODO:print interface name int do_list_entries(struct iptargs *ipt) { struct iptc_handle *handle; handle = iptc_init(ipt->table); const char *this; for (this=iptc_first_chain(handle); this; this=iptc_next_chain(handle)) { const struct ipt_entry *i; unsigned int num; if (ipt->chain && strcmp(ipt->chain, this) != 0) continue; print_header(this, handle); i = iptc_first_rule(this, handle); num = 0; while (i) { num++; printf("%d\t | ", num); print_entry(this, i, handle); i = iptc_next_rule(i, handle); } } iptc_free(handle); return 0; }
static void fwd_ipt_clear_ruleset_table(struct iptc_handle *h) { const char *chain; /* pass 1: flush all chains */ for( chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h) ) { iptc_flush_entries(chain, h); } /* pass 2: remove user defined chains */ for( chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h) ) { if( ! iptc_builtin(chain, h) ) iptc_delete_chain(chain, h); } }
int do_flush_entries(struct iptargs *ipt) { struct iptc_handle *handle; handle = iptc_init(ipt->table); printf("ipt->chain=%s\n",ipt->chain); if (!ipt->chain){ const char *this; for (this=iptc_first_chain(handle); this; this=iptc_next_chain(handle)) { iptc_flush_entries(this, handle); } } else {
static void fwd_ipt_delif_table(struct iptc_handle *h, const char *net) { const struct xt_entry_match *m; const struct ipt_entry *e; const char *chain, *comment; size_t off = 0, num = 0; /* iterate chains */ for( chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h) ) { /* iterate rules */ for( e = iptc_first_rule(chain, h), num = 0; e; e = iptc_next_rule(e, h), num++ ) { repeat_rule: /* skip entries w/o matches */ if( ! e->target_offset ) continue; /* iterate matches */ for( off = sizeof(struct ipt_entry); off < e->target_offset; off += m->u.match_size ) { m = (void *)e + off; /* yay */ if( ! strcmp(m->u.user.name, "comment") ) { /* better use struct_xt_comment_info but well... */ comment = (void *)m + sizeof(struct xt_entry_match); if( fwd_r_cmp("net=", comment, net) ) { e = iptc_next_rule(e, h); iptc_delete_num_entry(chain, num, h); if( e != NULL ) goto repeat_rule; else break; } } } } } }
int fetch_counts(const char *chain, struct iptable_data *dp, int max) { unsigned int num = 0; const char *thischain; const struct ipt_entry *ipt; struct iptc_handle *handle; handle = iptc_init("mangle"); if(handle) { for (thischain = iptc_first_chain(handle); thischain; thischain = iptc_next_chain(handle)) { if(!strcmp(thischain, chain)) { // go through rules in this chain for (ipt = iptc_first_rule(thischain, handle),num=0; ipt; ipt = iptc_next_rule(ipt, handle),num++) { if(!ipt || num >= max) break; dp->pcnt = ipt->counters.pcnt; dp->bcnt = ipt->counters.bcnt; strncpy(dp->iniface, ipt->ip.iniface, IFNAMSIZ); strncpy(dp->outiface, ipt->ip.outiface, IFNAMSIZ); dp->src.s_addr = ipt->ip.src.s_addr; dp->dst.s_addr = ipt->ip.dst.s_addr; dp->smsk.s_addr = ipt->ip.smsk.s_addr; dp->dmsk.s_addr = ipt->ip.dmsk.s_addr; dp->proto = ipt->ip.proto; dp++; // on to next } break; // no need to look at other chains } } iptc_free(handle); } // number of rules matched if == max then there may be more return (num); }
static int do_output(const char *tablename) { iptc_handle_t h; const char *chain = NULL; if (!tablename) return for_each_table(&do_output); h = iptc_init(tablename); if (!h) exit_error(OTHER_PROBLEM, "Can't initialize: %s\n", iptc_strerror(errno)); if (!binary) { time_t now = time(NULL); printf("# Generated by iptables-save v%s on %s", IPTABLES_VERSION, ctime(&now)); printf("*%s\n", tablename); /* Dump out chain names first, * thereby preventing dependency conflicts */ for (chain = iptc_first_chain(&h); chain; chain = iptc_next_chain(&h)) { printf(":%s ", chain); if (iptc_builtin(chain, h)) { struct ipt_counters count; printf("%s ", iptc_get_policy(chain, &count, &h)); printf("[%llu:%llu]\n", count.pcnt, count.bcnt); } else { printf("- [0:0]\n"); } } for (chain = iptc_first_chain(&h); chain; chain = iptc_next_chain(&h)) { const struct ipt_entry *e; /* Dump out rules */ e = iptc_first_rule(chain, &h); while(e) { print_rule(e, &h, chain, counters); e = iptc_next_rule(e, &h); } } now = time(NULL); printf("COMMIT\n"); printf("# Completed on %s", ctime(&now)); } else { /* Binary, huh? OK. */ exit_error(OTHER_PROBLEM, "Binary NYI\n"); } return 1; }
static int for_save_table() { int ret = 1; FILE *procfile = NULL; char tablename[] ="filter"; const char *returnvalue =NULL; time_t now = time(NULL); const char *target_name; procfile = fopen("/data/ip_tables_save_temp", "w+"); if (!procfile) return ret; struct iptc_handle *h; const char *chain = NULL; h = iptc_init(tablename); if (h == NULL) { xtables_load_ko(xtables_modprobe_program, false); h = iptc_init(tablename); } if (!h) xtables_error(OTHER_PROBLEM, "Cannot initialize: %s\n", iptc_strerror(errno)); printf("# for_save_table...LGE \n"); /* Dump out chain names first, * thereby preventing dependency conflicts */ for (chain = iptc_first_chain(h); chain; chain = iptc_next_chain(h)) { const struct ipt_entry *e; printf(":%s\n ", chain); if(!strcmp(chain,"OUTPUT")){ /* Dump out rules */ e = iptc_first_rule(chain, h); while(e) { target_name = iptc_get_target(e, h); if(!strcmp(target_name,"DROP")){ printf("target :%s\n ", target_name); printf("out_iface :%s\n ", e->ip.outiface); fprintf(procfile,"%s\t%s\n", target_name, e->ip.outiface); } e = iptc_next_rule(e, h); } } } //fputs(returnvalue, procfile); iptc_free(h); fclose(procfile); return ret; }
void genIPTablesRules(const std::string &filter, QueryData &results) { Row r; r["filter_name"] = filter; // Initialize the access to iptc auto handle = (struct iptc_handle *)iptc_init(filter.c_str()); if (handle == nullptr) { return; } // Iterate through chains for (auto chain = iptc_first_chain(handle); chain != nullptr; chain = iptc_next_chain(handle)) { r["chain"] = TEXT(chain); struct ipt_counters counters; auto policy = iptc_get_policy(chain, &counters, handle); if (policy != nullptr) { r["policy"] = TEXT(policy); r["packets"] = INTEGER(counters.pcnt); r["bytes"] = INTEGER(counters.bcnt); } else { r["policy"] = ""; r["packets"] = "0"; r["bytes"] = "0"; } const struct ipt_entry *prev_rule = nullptr; // Iterating through all the rules per chain for (const struct ipt_entry *chain_rule = iptc_first_rule(chain, handle); chain_rule; chain_rule = iptc_next_rule(prev_rule, handle)) { prev_rule = chain_rule; auto target = iptc_get_target(chain_rule, handle); if (target != nullptr) { r["target"] = TEXT(target); } else { r["target"] = ""; } if (chain_rule->target_offset) { r["match"] = "yes"; // fill protocol port details parseEntryMatch(chain_rule, r); } else { r["match"] = "no"; r["src_port"] = ""; r["dst_port"] = ""; } const struct ipt_ip *ip = &chain_rule->ip; parseIpEntry(ip, r); results.push_back(r); } // Rule iteration results.push_back(r); } // Chain iteration iptc_free(handle); }
// Delete all user-defined iptables chains. static int __lua_iptc_delete_user_chains(lua_State *L) { int i; const char *chain; const char *table = luaL_checkstring(L, 1); char *chains; unsigned int c, count = 0; i = find_table(table); if(i == -1) return eprintf("Invalid table: %s", table); if(!tables[i].handle) return eprintf("Invalid table: %s", table); chain = iptc_first_chain(tables[i].handle); while(chain) { count++; chain = iptc_next_chain(tables[i].handle); } chains = malloc(sizeof(ipt_chainlabel) * count); c = 0; chain = iptc_first_chain(tables[i].handle); while(chain) { strcpy(chains + c * sizeof(ipt_chainlabel), chain); c++; chain = iptc_next_chain(tables[i].handle); } for(c = 0; c < count; c++) { if(iptc_builtin(chains + c * sizeof(ipt_chainlabel), tables[i].handle)) continue; iptc_delete_chain(chains + c * sizeof(ipt_chainlabel), tables[i].handle); } free(chains); // XXX: Nope! Must copy chain names (as above, from iptables.c). #if 0 chain = iptc_first_chain(tables[i].handle); while(chain) { fprintf(stderr, "chain \"%s\", [%d]0x%08x\n", chain, i, tables[i].handle); if(!iptc_builtin(chain, tables[i].handle)) { fprintf(stderr, "iptc_delete_chain: %d\n", iptc_delete_chain(chain, tables[i].handle)); } chain = iptc_next_chain(tables[i].handle); } #endif return 0; }
/* * Get a list of the current firewall entries * @param fw_list list of firewall entries * @return 0 on success and errno on failure */ int netconf_get_fw(netconf_fw_t *fw_list) { const char **table; const char *chain; const struct ipt_entry *entry; struct iptc_handle *handle = NULL; /* Initialize list */ netconf_list_init(fw_list); /* Search all default tables */ for (table = &netconf_table_names[0]; *table; table++) { if (strcmp(*table, "filter") && strcmp(*table, "nat")) continue; if (!(handle = iptc_init(*table))) { fprintf(stderr, "%s\n", iptc_strerror(errno)); goto err; } /* Search all default chains */ for (chain = iptc_first_chain(handle); chain; chain = iptc_next_chain(handle)) { if (strcmp(chain, "INPUT") && strcmp(chain, "FORWARD") && strcmp(chain, "OUTPUT") && strcmp(chain, "PREROUTING") && strcmp(chain, "POSTROUTING") && strcmp(chain, "VSERVER") && strcmp(chain, "UPNP")) continue; /* Search all entries */ for (entry = iptc_first_rule(chain, handle); entry; entry = iptc_next_rule(entry, handle)) { int num = target_num(entry, handle); netconf_fw_t *fw = NULL; netconf_filter_t *filter = NULL; netconf_nat_t *nat = NULL; netconf_app_t *app = NULL; const struct ipt_entry_match *match; const struct ipt_entry_target *target; struct ipt_mac_info *mac = NULL; struct ipt_state_info *state = NULL; struct ipt_conntrack_info *conntrack = NULL; struct ipt_time_info *time = NULL; /* Only know about TCP/UDP */ if (!netconf_valid_ipproto(entry->ip.proto)) continue; /* Only know about target types in the specified tables */ if (!netconf_valid_target(num) || (netconf_table_name[num] && strncmp(netconf_table_name[num], *table, IPT_FUNCTION_MAXNAMELEN) != 0)) continue; /* Only know about specified target types */ if (netconf_valid_filter(num)) fw = (netconf_fw_t *) (filter = calloc(1, sizeof(netconf_filter_t))); else if (netconf_valid_nat(num)) fw = (netconf_fw_t *) (nat = calloc(1, sizeof(netconf_nat_t))); else if (num == NETCONF_APP) fw = (netconf_fw_t *) (app = calloc(1, sizeof(netconf_app_t))); else continue; if (!fw) { perror("calloc"); goto err; } netconf_list_add(fw, fw_list); /* Get IP addresses */ fw->match.src.ipaddr.s_addr = entry->ip.src.s_addr; fw->match.src.netmask.s_addr = entry->ip.smsk.s_addr; fw->match.dst.ipaddr.s_addr = entry->ip.dst.s_addr; fw->match.dst.netmask.s_addr = entry->ip.dmsk.s_addr; fw->match.flags |= (entry->ip.invflags & IPT_INV_SRCIP) ? NETCONF_INV_SRCIP : 0; fw->match.flags |= (entry->ip.invflags & IPT_INV_DSTIP) ? NETCONF_INV_DSTIP : 0; /* Get interface names */ strncpy(fw->match.in.name, entry->ip.iniface, IFNAMSIZ); strncpy(fw->match.out.name, entry->ip.outiface, IFNAMSIZ); fw->match.flags |= (entry->ip.invflags & IPT_INV_VIA_IN) ? NETCONF_INV_IN : 0; fw->match.flags |= (entry->ip.invflags & IPT_INV_VIA_OUT) ? NETCONF_INV_OUT : 0; fw->match.ipproto = entry->ip.proto; /* Get TCP port(s) */ if (entry->ip.proto == IPPROTO_TCP) { struct ipt_tcp *tcp = NULL; for_each_ipt_match(match, entry) { if (strncmp(match->u.user.name, "tcp", IPT_FUNCTION_MAXNAMELEN) != 0) continue; tcp = (struct ipt_tcp *) &match->data[0]; break; } if (tcp) { /* Match ports stored in host order for some stupid reason */ fw->match.src.ports[0] = htons(tcp->spts[0]); fw->match.src.ports[1] = htons(tcp->spts[1]); fw->match.dst.ports[0] = htons(tcp->dpts[0]); fw->match.dst.ports[1] = htons(tcp->dpts[1]); fw->match.flags |= (tcp->invflags & IPT_TCP_INV_SRCPT) ? NETCONF_INV_SRCPT : 0; fw->match.flags |= (tcp->invflags & IPT_TCP_INV_DSTPT) ? NETCONF_INV_DSTPT : 0; } } /* Get UDP port(s) */ else if (entry->ip.proto == IPPROTO_UDP) { struct ipt_udp *udp = NULL; for_each_ipt_match(match, entry) { if (strncmp(match->u.user.name, "udp", IPT_FUNCTION_MAXNAMELEN) != 0) continue; udp = (struct ipt_udp *) &match->data[0]; break; } if (udp) { /* Match ports stored in host order for some stupid reason */ fw->match.src.ports[0] = htons(udp->spts[0]); fw->match.src.ports[1] = htons(udp->spts[1]); fw->match.dst.ports[0] = htons(udp->dpts[0]); fw->match.dst.ports[1] = htons(udp->dpts[1]); fw->match.flags |= (udp->invflags & IPT_UDP_INV_SRCPT) ? NETCONF_INV_SRCPT : 0; fw->match.flags |= (udp->invflags & IPT_UDP_INV_DSTPT) ? NETCONF_INV_DSTPT : 0; } } /* Get source MAC address */ for_each_ipt_match(match, entry) { if (strncmp(match->u.user.name, "mac", IPT_FUNCTION_MAXNAMELEN) != 0) continue; mac = (struct ipt_mac_info *) &match->data[0]; break; } if (mac) { memcpy(fw->match.mac.octet, mac->srcaddr, ETHER_ADDR_LEN); fw->match.flags |= mac->invert ? NETCONF_INV_MAC : 0; } /* Get packet state */ for_each_ipt_match(match, entry) { if (strncmp(match->u.user.name, "state", IPT_FUNCTION_MAXNAMELEN) == 0) { state = (struct ipt_state_info *) &match->data[0]; break; } else if (strncmp(match->u.user.name, "conntrack", IPT_FUNCTION_MAXNAMELEN) == 0) { conntrack = (struct ipt_conntrack_info *) &match->data[0]; break; } } if (conntrack && (conntrack->match_flags & XT_CONNTRACK_STATE)) { fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_INVALID) ? NETCONF_INVALID : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_BIT(IP_CT_ESTABLISHED)) ? NETCONF_ESTABLISHED : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_BIT(IP_CT_RELATED)) ? NETCONF_RELATED : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_BIT(IP_CT_NEW)) ? NETCONF_NEW : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_UNTRACKED) ? NETCONF_UNTRACKED : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_SNAT) ? NETCONF_STATE_SNAT : 0; fw->match.state |= (conntrack->state_mask & XT_CONNTRACK_STATE_DNAT) ? NETCONF_STATE_DNAT : 0; } else if (state) { fw->match.state |= (state->statemask & IPT_STATE_INVALID) ? NETCONF_INVALID : 0; fw->match.state |= (state->statemask & IPT_STATE_BIT(IP_CT_ESTABLISHED)) ? NETCONF_ESTABLISHED : 0; fw->match.state |= (state->statemask & IPT_STATE_BIT(IP_CT_RELATED)) ? NETCONF_RELATED : 0; fw->match.state |= (state->statemask & IPT_STATE_BIT(IP_CT_NEW)) ? NETCONF_NEW : 0; } /* Get local time */ for_each_ipt_match(match, entry) { if (strncmp(match->u.user.name, "time", IPT_FUNCTION_MAXNAMELEN) != 0) continue; /* We added 8 bytes of day range at the end */ if (match->u.match_size < (IPT_ALIGN(sizeof(struct ipt_entry_match)) + IPT_ALIGN(sizeof(struct ipt_time_info) + 8))) continue; time = (struct ipt_time_info *) &match->data[0]; break; } if (time) { fw->match.days = time->weekdays_match; fw->match.secs[0] = time->daytime_start; fw->match.secs[1] = time->daytime_stop; } /* Set target type */ fw->target = num; target = (struct ipt_entry_target *) ((int) entry + entry->target_offset); /* Get filter target information */ if (filter) { if (!netconf_valid_dir(filter->dir = filter_dir(chain))) { fprintf(stderr, "error direction in %s\n", chain); goto err; } } /* Get NAT target information */ else if (nat) { struct ip_nat_multi_range *mr = (struct ip_nat_multi_range *) &target->data[0]; struct ip_nat_range *range = (struct ip_nat_range *) &mr->range[0]; /* Get mapped IP address */ nat->ipaddr.s_addr = range->min_ip; /* Get mapped TCP port(s) */ if (entry->ip.proto == IPPROTO_TCP) { nat->ports[0] = range->min.tcp.port; nat->ports[1] = range->max.tcp.port; } /* Get mapped UDP port(s) */ else if (entry->ip.proto == IPPROTO_UDP) { nat->ports[0] = range->min.udp.port; nat->ports[1] = range->max.udp.port; } } /* Get application specific port forward information */ else if (app) { struct ip_autofw_info *info = (struct ip_autofw_info *) &target->data[0]; app->proto = info->proto; app->dport[0] = info->dport[0]; app->dport[1] = info->dport[1]; app->to[0] = info->to[0]; app->to[1] = info->to[1]; } } } if (!iptc_commit(handle)) { fprintf(stderr, "%s\n", iptc_strerror(errno)); goto err; } iptc_free(handle); handle = NULL; }