diff options
Diffstat (limited to 'linux/conf/iptables/ip_blocker.c')
-rw-r--r-- | linux/conf/iptables/ip_blocker.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/linux/conf/iptables/ip_blocker.c b/linux/conf/iptables/ip_blocker.c new file mode 100644 index 0000000..c36a4ad --- /dev/null +++ b/linux/conf/iptables/ip_blocker.c @@ -0,0 +1,226 @@ +/* + * 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 <stdio.h> +#include <stdlib.h> +#include <errno.h> +#include <string.h> +#include <libiptc/libiptc.h> + +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; +} |