about summary refs log tree commit diff stats
path: root/linux/conf/iptables/ip_blocker.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/conf/iptables/ip_blocker.c')
-rw-r--r--linux/conf/iptables/ip_blocker.c226
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;
+}