/* Returns a netconf_target index */ static int target_num(const struct ipt_entry *entry, struct iptc_handle *handle) { const char *name = iptc_get_target(entry, handle); int i; if (!name) return -1; for (i = NETCONF_DROP; i < NETCONF_TARGET_MAX; i++) { if (strncmp(name, netconf_target_name[i], IPT_FUNCTION_MAXNAMELEN) == 0) return i; } return -ENOENT; }
/* We want this to be readable, so only print out neccessary fields. * Because that's the kind of world I want to live in. */ static void print_rule(const struct ipt_entry *e, iptc_handle_t *h, const char *chain, int counters) { struct ipt_entry_target *t; const char *target_name; /* print counters */ if (counters) printf("[%llu:%llu] ", e->counters.pcnt, e->counters.bcnt); /* print chain name */ printf("-A %s ", chain); /* Print IP part. */ print_ip("-s", e->ip.src.s_addr,e->ip.smsk.s_addr, e->ip.invflags & IPT_INV_SRCIP); print_ip("-d", e->ip.dst.s_addr, e->ip.dmsk.s_addr, e->ip.invflags & IPT_INV_DSTIP); print_iface('i', e->ip.iniface, e->ip.iniface_mask, e->ip.invflags & IPT_INV_VIA_IN); print_iface('o', e->ip.outiface, e->ip.outiface_mask, e->ip.invflags & IPT_INV_VIA_OUT); print_proto(e->ip.proto, e->ip.invflags & IPT_INV_PROTO); if (e->ip.flags & IPT_F_FRAG) printf("%s-f ", e->ip.invflags & IPT_INV_FRAG ? "! " : ""); /* Print matchinfo part */ if (e->target_offset) { IPT_MATCH_ITERATE(e, print_match, &e->ip); } /* Print target name */ target_name = iptc_get_target(e, h); if (target_name && (*target_name != '\0')) printf("-j %s ", target_name); /* Print targinfo part */ t = ipt_get_target((struct ipt_entry *)e); if (t->u.user.name[0]) { struct iptables_target *target = find_target(t->u.user.name, TRY_LOAD); if (!target) { fprintf(stderr, "Can't find library for target `%s'\n", t->u.user.name); exit(1); } if (target->save) target->save(&e->ip, t); else { /* If the target size is greater than ipt_entry_target * there is something to be saved, we just don't know * how to print it */ if (t->u.target_size != sizeof(struct ipt_entry_target)) { fprintf(stderr, "Target `%s' is missing " "save function\n", t->u.user.name); exit(1); } } } printf("\n"); }
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 iptc_delete_rule(const char *table, const char *chain, const char *protocol, const char *iniface, const char *outiface, const char *src, const char *dest, const char *srcports, const char *destports, const char *target, const char *dnat_to) { iptc_handle_t handle; const struct ipt_entry *e; ipt_chainlabel labelit; int i, result; unsigned long int s_src = INADDR_NONE, s_dest = INADDR_NONE; if (src) s_src = inet_addr(src); if (dest) s_dest = inet_addr(dest); handle = iptc_init(table); if (!handle) { trace(1, "libiptc error: Can't initialize table %s, %s", table, iptc_strerror(errno)); return; } strncpy(labelit, chain, sizeof(ipt_chainlabel)); result = iptc_is_chain(chain, handle); if (!result) { trace(1, "libiptc error: Chain %s does not exist!", chain); return; } /* check through rules to find match */ for (e = iptc_first_rule(chain, &handle), i=0; e; e = iptc_next_rule(e, &handle), i++) { if (s_src != INADDR_NONE && e->ip.src.s_addr != s_src) continue; if (s_dest != INADDR_NONE && e->ip.dst.s_addr != s_dest) continue; if (iniface && strcmp(e->ip.iniface, iniface) != 0) continue; if (outiface && strcmp(e->ip.outiface, outiface) != 0) continue; if (protocol && strcmp(protocol, "TCP") == 0 && e->ip.proto != IPPROTO_TCP) continue; if (protocol && strcmp(protocol, "UDP") == 0 && e->ip.proto != IPPROTO_UDP) continue; if ((srcports || destports) && IPT_MATCH_ITERATE(e, matchcmp, srcports, destports) == 0) continue; if (target && strcmp(target, iptc_get_target(e, &handle)) != 0) continue; if (dnat_to && strcmp(target, "DNAT") == 0) { struct ipt_entry_target *t; struct ip_nat_multi_range *mr; struct ip_nat_range *r, range; t = (void *) e+e->target_offset; mr = (void *) &t->data; if (mr->rangesize != 1) continue; /* we have only single dnat_to target now */ r = mr->range; parse_range(dnat_to, &range); if (r->flags == range.flags && r->min_ip == range.min_ip && r->max_ip == range.max_ip && r->min.all == range.min.all && r->max.all == range.max.all) { break; } } break; } if (!e) return; result = iptc_delete_num_entry(chain, i, &handle); if (!result) { trace(1, "libiptc error: Delete error, %s", iptc_strerror(errno)); return; } result = iptc_commit(&handle); if (!result) { trace(1, "libiptc error: Commit error, %s", iptc_strerror(errno)); return; } else trace(3, "deleted rule from block successfully"); }
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); }
/* We want this to be readable, so only print out neccessary fields. * Because that's the kind of world I want to live in. */ extern EXPORT const char* output_rule4(const struct ipt_entry *e, void *h, const char *chain, int counters) { const struct xt_entry_target *t; const char *target_name; char buf[BUFSIZ]; /* print counters for iptables-save */ if (counters > 0) ptr += sprintf(ptr,"[%llu:%llu] ", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt); /* print chain name */ ptr += sprintf(ptr,"-A %s", chain); /* Print IP part. */ print_ip("-s", e->ip.src.s_addr, e->ip.smsk.s_addr, e->ip.invflags & IPT_INV_SRCIP); print_ip("-d", e->ip.dst.s_addr, e->ip.dmsk.s_addr, e->ip.invflags & IPT_INV_DSTIP); print_iface('i', e->ip.iniface, e->ip.iniface_mask, e->ip.invflags & IPT_INV_VIA_IN); print_iface('o', e->ip.outiface, e->ip.outiface_mask, e->ip.invflags & IPT_INV_VIA_OUT); print_proto(e->ip.proto, e->ip.invflags & XT_INV_PROTO); if (e->ip.flags & IPT_F_FRAG) ptr += sprintf(ptr,"%s -f", e->ip.invflags & IPT_INV_FRAG ? " !" : ""); /* Print matchinfo part */ if (e->target_offset) { IPT_MATCH_ITERATE(e, print_match_save, &e->ip); } /* print counters for iptables -R */ if (counters < 0) ptr += sprintf(ptr," -c %llu %llu", (unsigned long long)e->counters.pcnt, (unsigned long long)e->counters.bcnt); /* Print target name */ target_name = iptc_get_target(e, h); #ifdef OLD_IPTABLES if (target_name && (*target_name != '\0')) #ifdef IPT_F_GOTO ptr += sprintf(ptr," -%c %s", e->ip.flags & IPT_F_GOTO ? 'g' : 'j', target_name); #else ptr += sprintf(ptr," -j %s", target_name); #endif #endif /* Print targinfo part */ t = ipt_get_target((struct ipt_entry *)e); if (t->u.user.name[0]) { const struct xtables_target *target = xtables_find_target(t->u.user.name, XTF_TRY_LOAD); if (!target) { fprintf(stderr, "Can't find library for target `%s'\n", t->u.user.name); return NULL; } #ifndef OLD_IPTABLES ptr += sprintf(ptr, " -j %s", target->alias ? target->alias(t) : target_name); #endif if (target){ if (target->save){ memset(buf, 0, sizeof(buf)); switchStdout("/dev/null"); setvbuf(stdout, buf, _IOLBF, BUFSIZ); target->save(&e->ip, t); fflush(stdout); setbuf(stdout, NULL); revertStdout(); ptr += sprintf(ptr, "%s", buf); } else { /* If the target size is greater than xt_entry_target * there is something to be saved, we just don't know * how to print it */ if (t->u.target_size != sizeof(struct xt_entry_target)) { fprintf(stderr, "Target `%s' is missing " "save function\n", t->u.user.name); return NULL; } } } } #ifndef OLD_IPTABLES else if (target_name && (*target_name != '\0')){ #ifdef IPT_F_GOTO ptr += sprintf(ptr, " -%c %s", e->ip.flags & IPT_F_GOTO ? 'g' : 'j', target_name); #else ptr += sprintf(ptr, " -j %s", target_name); #endif } #endif *ptr = '\0'; ptr = buffer; return buffer; }