/* * Souce: https://bani.com.br/2012/05/programmatically-managing-iptables-rules-in-c-iptc/ * * changed by silvino at bk dot ru to meet personal taste * to query https://tldp.org/HOWTO/Querying-libiptc-HOWTO/mfunction.html */ #define BUFSIZ 64 #include #include #include #include #include struct { struct ipt_entry entry; struct xt_standard_target target; } entry; //struct xtc_handle *h; static int insert_rule ( //struct xtc_handle *h, const char *table, const char *chain, unsigned int src, int inverted_src, unsigned int dest, int inverted_dst, const char *target) { struct xtc_handle *h; int ret = 1; h = iptc_init (table); if (!h) { fprintf (stderr, "Could not init IPTC library: %s\n", iptc_strerror (errno)); goto out; } entry.entry.ip.src.s_addr = INADDR_ANY; entry.entry.ip.smsk.s_addr = 0; entry.entry.ip.dst.s_addr = INADDR_ANY; entry.entry.ip.dmsk.s_addr = 0; /* target */ entry.target.target.u.user.target_size = XT_ALIGN (sizeof (struct xt_standard_target)); strncpy (entry.target.target.u.user.name, target, sizeof (entry.target.target.u.user.name)); /* entry */ entry.entry.target_offset = sizeof (struct ipt_entry); entry.entry.next_offset = entry.entry.target_offset + entry.target.target.u.user.target_size; if (src) { entry.entry.ip.src.s_addr = src; entry.entry.ip.smsk.s_addr = 0xFFFFFFFF; if (inverted_src) entry.entry.ip.invflags |= IPT_INV_SRCIP; } if (dest) { entry.entry.ip.dst.s_addr = dest; entry.entry.ip.dmsk.s_addr = 0xFFFFFFFF; if (inverted_dst) entry.entry.ip.invflags |= IPT_INV_DSTIP; } if (!iptc_append_entry (chain, (struct ipt_entry *) &entry, h)) { fprintf (stderr, "Could not insert a rule in iptables (table %s): %s\n", table, iptc_strerror (errno)); return ret; } if (!iptc_commit (h)) { fprintf (stderr, "Could not commit changes in iptables (table %s): %s\n", table, iptc_strerror (errno)); return ret; } ret = 0; out: if (h) iptc_free(h); return ret; } void *xrealloc(void *ptr, size_t size) { ptr = realloc(ptr, size); if (ptr == NULL && size != 0) { exit(EXIT_FAILURE); } return ptr; } char *xstrdup(const char *s) { char *t; if (s == NULL) return NULL; t = strdup(s); if (t == NULL) { exit(EXIT_FAILURE); } return t; } char *file_read_line_alloc(FILE *fp) { char buf[BUFSIZ]; unsigned int buf_len; char *line = NULL; unsigned int line_size = 0; int got_nl = 0; buf[0] = '\0'; while (fgets(buf, BUFSIZ, fp)) { buf_len = strlen(buf); if (buf[buf_len - 1] == '\n') { buf_len--; buf[buf_len] = '\0'; got_nl = 1; } if (line) { line_size += buf_len; line = xrealloc(line, line_size + 1); strncat(line, buf, line_size); } else { line_size = buf_len + 1; line = xstrdup(buf); } if (got_nl) break; } return line; } int main (int argc, char **argv) { const char *chain_in="blockip_in"; const char *chain_out="blockip_out"; long int total=0; if(argc > 1 && strcmp(argv[1], "-h") == 0){ printf("\nip_blocker accepts a list of ip's from a file or stdin\n"); printf("ip's are added to %s and %s chains\n\n", chain_in, chain_out); printf("ip_blocker [file]\n"); exit(0); } unsigned int a, b, ret; char *line = NULL; FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin; if (!fp) { fprintf (stderr, "error: file open failed '%s'.\n", argv[1]); exit(EXIT_FAILURE); } memset (&entry, 0, sizeof (entry)); while (line = file_read_line_alloc(fp)) { inet_pton (AF_INET, line, &a); ret = insert_rule ( // handler //h, //const char *table, "filter", //const char *chain, chain_in, //unsigned int src, a, //int inverted_src, 0, //unsigned int dest, NULL, //int inverted_dst, 0, //const char *target "DROP"); if(ret == 1){ printf("Failed to add %s to %s does %s chain exists ?", line, chain_in, chain_in); free (line); fclose(fp); exit(EXIT_FAILURE); } ret = insert_rule ( // handler //h, //const char *table, "filter", //const char *chain, chain_out, //unsigned int src, NULL, //int inverted_src, 0, //unsigned int dest, a, //int inverted_dst, 0, //const char *target "DROP"); if(ret == 1){ printf("Failed to add %s to %s does %s chain exists ?", line, chain_out, chain_out); free (line); fclose(fp); exit(EXIT_FAILURE); } total = total + 1; free (line); line = NULL; } if(fp){ fclose(fp); } printf ("total ip's added; %i\n", total); return 0; }