summaryrefslogtreecommitdiffstats
path: root/src/plugins/ifw
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/ifw')
-rw-r--r--src/plugins/ifw/black_list.c76
-rw-r--r--src/plugins/ifw/black_list.h20
-rw-r--r--src/plugins/ifw/ifw.h48
-rw-r--r--src/plugins/ifw/ifw_dbus.c456
-rw-r--r--src/plugins/ifw/ifw_dbus.h43
-rw-r--r--src/plugins/ifw/ipset.c89
-rw-r--r--src/plugins/ifw/ipset.h22
-rw-r--r--src/plugins/ifw/libnl_ifw.c62
-rw-r--r--src/plugins/ifw/libnl_ifw.h35
-rw-r--r--src/plugins/ifw/list.h155
-rw-r--r--src/plugins/ifw/plugin.c224
-rw-r--r--src/plugins/ifw/report_list.c81
-rw-r--r--src/plugins/ifw/report_list.h24
-rw-r--r--src/plugins/ifw/white_list.c119
-rw-r--r--src/plugins/ifw/white_list.h23
15 files changed, 1477 insertions, 0 deletions
diff --git a/src/plugins/ifw/black_list.c b/src/plugins/ifw/black_list.c
new file mode 100644
index 0000000..1e7dbbb
--- /dev/null
+++ b/src/plugins/ifw/black_list.c
@@ -0,0 +1,76 @@
+#include "black_list.h"
+#include "ipset.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+void black_list_init(black_list_t *list) {
+ INIT_LIST_HEAD(list);
+}
+
+void black_list_add(black_list_t *list, msg_usr_t *attack) {
+ black_list_cell_t *cell;
+
+ cell = malloc(sizeof(black_list_cell_t));
+ if (!cell) {
+ fprintf(stderr, "unable to alloc enough memory for black list cell, skipping\n");
+ return;
+ }
+ cell->info = *attack;
+ INIT_LIST_HEAD(&cell->list);
+ list_add_tail(&cell->list, list);
+
+ ipset_blacklist_add(cell->info.s_addr);
+}
+
+black_list_cell_t *black_list_find(black_list_t *list, u_int32_t addr) {
+ struct list_head *entry;
+
+ __list_for_each(entry, list) {
+ black_list_cell_t *cell;
+ cell = list_entry(entry, black_list_cell_t, list);
+ if (cell->info.s_addr == addr) {
+ return cell;
+ }
+ }
+
+ return NULL;
+}
+
+void black_list_remove(black_list_t *list, u_int32_t addr) {
+ black_list_cell_t *cell, *n, *prev;
+
+ ipset_blacklist_remove(addr);
+
+ prev = NULL;
+ list_for_each_entry_safe(cell, n, list, list) {
+ if (prev)
+ free(prev);
+ if (cell->info.s_addr == addr) {
+ list_del(&cell->list);
+ prev = cell;
+ } else {
+ prev = NULL;
+ }
+ }
+ if (prev)
+ free(prev);
+}
+
+
+void black_list_print(black_list_t *list) {
+ struct list_head *entry;
+
+ printf("* black list {\n");
+ __list_for_each(entry, list) {
+ black_list_cell_t *cell;
+ struct in_addr addr;
+ cell = list_entry(entry, black_list_cell_t, list);
+ addr.s_addr = cell->info.s_addr;
+ printf("%s,\n", inet_ntoa(addr));
+ }
+ printf("} black list *\n");
+}
diff --git a/src/plugins/ifw/black_list.h b/src/plugins/ifw/black_list.h
new file mode 100644
index 0000000..4cfe74b
--- /dev/null
+++ b/src/plugins/ifw/black_list.h
@@ -0,0 +1,20 @@
+#ifndef BLACK_LIST_H
+#define BLACK_LIST_H
+
+#include "list.h"
+typedef struct list_head black_list_t;
+
+#include "ifw.h"
+
+typedef struct {
+ struct list_head list;
+ msg_usr_t info;
+} black_list_cell_t;
+
+void black_list_init(black_list_t *list);
+void black_list_add(black_list_t *list, msg_usr_t *attack);
+black_list_cell_t *black_list_find(black_list_t *list, u_int32_t addr);
+void black_list_remove(black_list_t *list, u_int32_t addr);
+void black_list_print(black_list_t *list);
+
+#endif /* BLACK_LIST_H */
diff --git a/src/plugins/ifw/ifw.h b/src/plugins/ifw/ifw.h
new file mode 100644
index 0000000..f007b0f
--- /dev/null
+++ b/src/plugins/ifw/ifw.h
@@ -0,0 +1,48 @@
+#ifndef IFW_H
+#define IFW_H
+
+#include "plugin.h"
+
+#define IFW_DBUS_PATH PLUGIN_ROOT_PATH "/ifw"
+#define IFW_DBUS_INTERFACE PLUGIN_ROOT_INTF ".ifw"
+
+#include <sys/types.h>
+#include "libnl_ifw.h"
+
+#define IFW_SYSCONF_ROOT "/etc/ifw/"
+#define IFW_BLACKLIST_FILENAME IFW_SYSCONF_ROOT "blacklist"
+#define IFW_WHITELIST_FILENAME IFW_SYSCONF_ROOT "whitelist"
+
+typedef enum {
+ IFW_MODE_AUTO,
+ IFW_MODE_INTERACTIVE
+} ifw_mode_t;
+
+typedef struct {
+ long timestamp_sec; /* date */
+ char indev_name[IFNAMSIZ]; /* input interface */
+ char prefix[PREFSIZ]; /* summary of attack */
+ int sensor; /* sensor the alert come from */
+ int protocol; /* Protocol */
+ u_int32_t s_addr; /* source address */
+ u_int16_t d_port; /* destination port UDP/TCP */
+ u_int8_t icmp_type; /* icmp type */
+} msg_usr_t;
+
+typedef struct popup_verdict {
+ int seq;
+ int bl;
+} popup_verdict_t;
+
+#include "black_list.h"
+#include "white_list.h"
+#include "report_list.h"
+
+typedef struct {
+ ifw_mode_t mode;
+ black_list_t blacklist;
+ report_list_t reports;
+ white_list_t whitelist;
+} ifw_t;
+
+#endif /* IFW_H */
diff --git a/src/plugins/ifw/ifw_dbus.c b/src/plugins/ifw/ifw_dbus.c
new file mode 100644
index 0000000..82b2675
--- /dev/null
+++ b/src/plugins/ifw/ifw_dbus.c
@@ -0,0 +1,456 @@
+#include <stdio.h>
+
+#include "ifw_dbus.h"
+
+static void ifw_dbus_notify_simple_signal(DBusConnection *bus, char *signal) {
+ DBusMessage *message;
+
+ message = dbus_message_new_signal(IFW_DBUS_PATH,
+ IFW_DBUS_INTERFACE,
+ signal);
+ dbus_connection_send(bus, message, NULL);
+ dbus_connection_flush(bus);
+ dbus_message_unref(message);
+}
+
+void ifw_dbus_apply_report_verdict(DBusConnection *connection, ifw_t *ifw, report_list_cell_t *report, int do_blacklist) {
+ if (do_blacklist) {
+ if (!black_list_find(&ifw->blacklist, report->info.s_addr)) {
+ printf("blacklisting seq %d\n", report->seq);
+ black_list_add(&ifw->blacklist, &report->info);
+ ifw_dbus_notify_blacklist(connection, &report->info);
+ } else {
+ printf("(seq %d) addr %u already in blacklist\n", report->seq, report->info.s_addr);
+ }
+ } else {
+ printf("ignoring seq %d\n", report->seq);
+ }
+ report->processed = 1;
+}
+
+/* notify frontends of a new attack with a DBus signal */
+void ifw_dbus_notify_attack(DBusConnection *bus, report_list_cell_t *report) {
+ DBusMessage *message;
+
+ message = dbus_message_new_signal(IFW_DBUS_PATH,
+ IFW_DBUS_INTERFACE,
+ "Attack");
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_UINT32,
+ report->info.timestamp_sec,
+ DBUS_TYPE_STRING,
+ report->info.indev_name,
+ DBUS_TYPE_STRING,
+ report->info.prefix,
+ DBUS_TYPE_UINT32,
+ report->info.sensor,
+ DBUS_TYPE_UINT32,
+ report->info.protocol,
+ DBUS_TYPE_UINT32,
+ report->info.s_addr,
+ DBUS_TYPE_UINT32,
+ report->info.d_port,
+ DBUS_TYPE_UINT32,
+ report->info.icmp_type,
+ DBUS_TYPE_UINT32,
+ report->seq,
+ DBUS_TYPE_UINT32,
+ report->processed,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(bus, message, NULL);
+ dbus_connection_flush(bus);
+ dbus_message_unref(message);
+}
+
+/* notify frontends of a new blacklist with a DBus signal */
+void ifw_dbus_notify_blacklist(DBusConnection *bus, msg_usr_t *attack) {
+ DBusMessage *message;
+
+ message = dbus_message_new_signal(IFW_DBUS_PATH,
+ IFW_DBUS_INTERFACE,
+ "Blacklist");
+
+ dbus_message_append_args(message,
+ DBUS_TYPE_UINT32,
+ attack->timestamp_sec,
+ DBUS_TYPE_STRING,
+ attack->indev_name,
+ DBUS_TYPE_STRING,
+ attack->prefix,
+ DBUS_TYPE_UINT32,
+ attack->sensor,
+ DBUS_TYPE_UINT32,
+ attack->protocol,
+ DBUS_TYPE_UINT32,
+ attack->s_addr,
+ DBUS_TYPE_UINT32,
+ attack->d_port,
+ DBUS_TYPE_UINT32,
+ attack->icmp_type,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(bus, message, NULL);
+ dbus_connection_flush(bus);
+ dbus_message_unref(message);
+}
+
+/* notify frontends of a new whitelist with a DBus signal */
+void ifw_dbus_notify_whitelist(DBusConnection *bus, u_int32_t addr) {
+ DBusMessage *message;
+
+ message = dbus_message_new_signal(IFW_DBUS_PATH,
+ IFW_DBUS_INTERFACE,
+ "Whitelist");
+ dbus_message_append_args(message,
+ DBUS_TYPE_UINT32,
+ addr,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(bus, message, NULL);
+ dbus_connection_flush(bus);
+ dbus_message_unref(message);
+}
+
+/* notify frontends that ifw data isn't usable with a DBus signal */
+void ifw_dbus_notify_clear(DBusConnection *bus) {
+ ifw_dbus_notify_simple_signal(bus, "Clear");
+}
+
+/* notify frontends that ifw has just been started */
+void ifw_dbus_notify_init(DBusConnection *bus) {
+ ifw_dbus_notify_simple_signal(bus, "Init");
+}
+
+/* notify frontends that a user is aware of the attacks */
+void ifw_dbus_notify_alert_ack(DBusConnection *bus) {
+ ifw_dbus_notify_simple_signal(bus, "AlertAck");
+}
+
+/* notify frontends that a user is wants to review the attacks */
+void ifw_dbus_notify_manage_request(DBusConnection *bus) {
+ ifw_dbus_notify_simple_signal(bus, "ManageRequest");
+}
+
+DBusHandlerResult ifw_dbus_get_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_UINT32,
+ ifw->mode,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_set_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ DBusMessage *reply;
+ ifw_mode_t mode;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &mode,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_set_mode(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ printf("setting new ifw mode : %s\n", mode == IFW_MODE_AUTO ? "auto" : mode == IFW_MODE_INTERACTIVE ? "interactive" : "unknown");
+ ifw->mode = mode;
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_UINT32,
+ ifw->mode,
+ DBUS_TYPE_INVALID);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_get_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ struct list_head *entry;
+ DBusMessage *reply;
+ char include_processed;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &include_processed,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_get_reports(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ reply = dbus_message_new_method_return(message);
+ __list_for_each(entry, &ifw->reports) {
+ report_list_cell_t *cell;
+ cell = list_entry(entry, report_list_cell_t, list);
+ if (cell->processed && !include_processed) {
+ continue;
+ }
+ dbus_message_append_args(reply,
+ DBUS_TYPE_UINT32,
+ cell->info.timestamp_sec,
+ DBUS_TYPE_STRING,
+ cell->info.indev_name,
+ DBUS_TYPE_STRING,
+ cell->info.prefix,
+ DBUS_TYPE_UINT32,
+ cell->info.sensor,
+ DBUS_TYPE_UINT32,
+ cell->info.protocol,
+ DBUS_TYPE_UINT32,
+ cell->info.s_addr,
+ DBUS_TYPE_UINT32,
+ cell->info.d_port,
+ DBUS_TYPE_UINT32,
+ cell->info.icmp_type,
+ DBUS_TYPE_UINT32,
+ cell->seq,
+ DBUS_TYPE_UINT32,
+ cell->processed,
+ DBUS_TYPE_INVALID);
+ }
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_get_blacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ struct list_head *entry;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ __list_for_each(entry, &ifw->blacklist) {
+ black_list_cell_t *cell;
+ cell = list_entry(entry, black_list_cell_t, list);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_UINT32,
+ cell->info.timestamp_sec,
+ DBUS_TYPE_STRING,
+ cell->info.indev_name,
+ DBUS_TYPE_STRING,
+ cell->info.prefix,
+ DBUS_TYPE_UINT32,
+ cell->info.sensor,
+ DBUS_TYPE_UINT32,
+ cell->info.protocol,
+ DBUS_TYPE_UINT32,
+ cell->info.s_addr,
+ DBUS_TYPE_UINT32,
+ cell->info.d_port,
+ DBUS_TYPE_UINT32,
+ cell->info.icmp_type,
+ DBUS_TYPE_INVALID);
+ }
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_set_blacklist_verdict(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ DBusMessage *reply;
+ int seq, do_blacklist;
+ report_list_cell_t *report;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &seq,
+ DBUS_TYPE_UINT32,
+ &do_blacklist,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_blacklist(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ report = report_list_find_seq(&ifw->reports, seq);
+ if (report) {
+ ifw_dbus_apply_report_verdict(connection, ifw, report, do_blacklist);
+ } else {
+ fprintf(stderr, "unable find sequence number in report list, skipping\n");
+ }
+
+ black_list_print(&ifw->blacklist);
+ report_list_print(&ifw->reports);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_unblacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ DBusMessage *reply;
+ u_int32_t addr;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &addr,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_blacklist(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ black_list_remove(&ifw->blacklist, addr);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_get_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ struct list_head *entry;
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(message);
+ __list_for_each(entry, &ifw->whitelist) {
+ white_list_cell_t *cell;
+ cell = list_entry(entry, white_list_cell_t, list);
+ dbus_message_append_args(reply,
+ DBUS_TYPE_UINT32,
+ cell->addr,
+ DBUS_TYPE_INVALID);
+ }
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ DBusMessage *reply;
+ u_int32_t addr;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &addr,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_whitelist(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ if (!white_list_find(&ifw->whitelist, addr)) {
+ printf("whitelisting addr %u\n", addr);
+ white_list_add(&ifw->whitelist, addr);
+ } else {
+ printf("addr %u already in whitelist\n", addr);
+ }
+ white_list_print(&ifw->whitelist);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ ifw_dbus_notify_whitelist(connection, addr);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_unwhitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusError error;
+ DBusMessage *reply;
+ u_int32_t addr;
+
+ dbus_error_init (&error);
+ if (!dbus_message_get_args (message,
+ &error,
+ DBUS_TYPE_UINT32,
+ &addr,
+ DBUS_TYPE_INVALID)) {
+ fprintf(stderr, "ifw_dbus_whitelist(): failed to read D-BUS message args: %s\n", error.message);
+ dbus_error_free (&error);
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ }
+ dbus_error_free (&error);
+
+ printf("remove addr from whitelist %u\n", addr);
+ white_list_remove(&ifw->whitelist, addr);
+
+ white_list_print(&ifw->whitelist);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_clear_processed_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusMessage *reply;
+
+ report_list_clear_processed(&ifw->reports);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_send_alert_ack(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusMessage *reply;
+
+ ifw_dbus_notify_alert_ack(connection);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
+DBusHandlerResult ifw_dbus_send_manage_request(DBusConnection *connection, DBusMessage *message, ifw_t *ifw) {
+ DBusMessage *reply;
+
+ ifw_dbus_notify_manage_request(connection);
+
+ reply = dbus_message_new_method_return(message);
+ dbus_connection_send(connection, reply, NULL);
+ dbus_connection_flush(connection);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
diff --git a/src/plugins/ifw/ifw_dbus.h b/src/plugins/ifw/ifw_dbus.h
new file mode 100644
index 0000000..a4385db
--- /dev/null
+++ b/src/plugins/ifw/ifw_dbus.h
@@ -0,0 +1,43 @@
+#ifndef IFW_DBUS_H
+#define IFW_DBUS_H
+
+#include <dbus/dbus.h>
+#include "ifw.h"
+
+void ifw_dbus_apply_report_verdict(DBusConnection *connection, ifw_t *ifw, report_list_cell_t *report, int do_blacklist);
+
+/* notify frontends of a new attack with a DBus signal */
+void ifw_dbus_notify_attack(DBusConnection *bus, report_list_cell_t *report);
+
+/* notify frontends of a new whitelist with a DBus signal */
+void ifw_dbus_notify_whitelist(DBusConnection *bus, u_int32_t addr);
+
+/* notify frontends of a new blacklist with a DBus signal */
+void ifw_dbus_notify_blacklist(DBusConnection *bus, msg_usr_t *attack);
+
+/* notify frontends that ifw data isn't usable with a DBus signal */
+void ifw_dbus_notify_clear(DBusConnection *bus);
+
+/* notify frontends that ifw has just been started */
+void ifw_dbus_notify_init(DBusConnection *bus);
+
+/* notify frontends that a user is aware of the attacks */
+void ifw_dbus_notify_alert_ack(DBusConnection *bus);
+
+/* notify frontends that a user is wants to review the attacks */
+void ifw_dbus_notify_manage_request(DBusConnection *bus);
+
+DBusHandlerResult ifw_dbus_get_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_set_mode(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_get_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_get_blacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_set_blacklist_verdict(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_unblacklist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_get_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_whitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_unwhitelist(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_clear_processed_reports(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_send_alert_ack(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+DBusHandlerResult ifw_dbus_send_manage_request(DBusConnection *connection, DBusMessage *message, ifw_t *ifw);
+
+#endif /* IFW_DBUS_H */
diff --git a/src/plugins/ifw/ipset.c b/src/plugins/ifw/ipset.c
new file mode 100644
index 0000000..74ca06e
--- /dev/null
+++ b/src/plugins/ifw/ipset.c
@@ -0,0 +1,89 @@
+#include "ipset.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+
+#define CMD_MAX_SIZE 1024
+
+#ifdef IPSET_DEBUG
+#define DPRINTF(s) printf("%s\n", s)
+#else
+#define DPRINTF(s)
+#endif
+
+void ipset_init() {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -N " IPSET_BLACKLIST_NAME " iptree --timeout " IPSET_BLACKLIST_TIMEOUT);
+ DPRINTF(cmd);
+ system(cmd);
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -N " IPSET_WHITELIST_NAME " iptree");
+ DPRINTF(cmd);
+ system(cmd);
+}
+
+void ipset_destroy() {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -X " IPSET_BLACKLIST_NAME);
+ DPRINTF(cmd);
+ system(cmd);
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -X " IPSET_WHITELIST_NAME);
+ DPRINTF(cmd);
+ system(cmd);
+}
+
+/* void ipset_blacklist_load(char *filename) { */
+/* char cmd[CMD_MAX_SIZE]; */
+/* snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -R < %s", filename); */
+/* DPRINTF(cmd); */
+/* system(cmd); */
+/* } */
+
+/* void ipset_blacklist_save(char *filename) { */
+/* char cmd[CMD_MAX_SIZE]; */
+/* snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -S " IPSET_BLACKLIST_NAME " > %s", filename); */
+/* DPRINTF(cmd); */
+/* system(cmd); */
+/* } */
+
+/* void ipset_whitelist_load(char *filename) { */
+/* char cmd[CMD_MAX_SIZE]; */
+/* snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -R < %s", filename); */
+/* DPRINTF(cmd); */
+/* system(cmd); */
+/* } */
+
+/* void ipset_whitelist_save(char *filename) { */
+/* char cmd[CMD_MAX_SIZE]; */
+/* snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -S " IPSET_WHITELIST_NAME " > %s", filename); */
+/* DPRINTF(cmd); */
+/* system(cmd); */
+/* } */
+
+void ipset_blacklist_add(u_int32_t addr) {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -A " IPSET_BLACKLIST_NAME " %u", ntohl(addr));
+ DPRINTF(cmd);
+ system(cmd);
+}
+
+void ipset_blacklist_remove(u_int32_t addr) {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -D " IPSET_BLACKLIST_NAME " %u", ntohl(addr));
+ DPRINTF(cmd);
+ system(cmd);
+}
+
+void ipset_whitelist_add(u_int32_t addr) {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -A " IPSET_WHITELIST_NAME " %u", ntohl(addr));
+ DPRINTF(cmd);
+ system(cmd);
+}
+
+void ipset_whitelist_remove(u_int32_t addr) {
+ char cmd[CMD_MAX_SIZE];
+ snprintf(cmd, CMD_MAX_SIZE, IPSET_CMD " -D " IPSET_WHITELIST_NAME " %u", ntohl(addr));
+ DPRINTF(cmd);
+ system(cmd);
+}
diff --git a/src/plugins/ifw/ipset.h b/src/plugins/ifw/ipset.h
new file mode 100644
index 0000000..a78395a
--- /dev/null
+++ b/src/plugins/ifw/ipset.h
@@ -0,0 +1,22 @@
+#ifndef IPSET_H
+#define IPSET_H
+
+#define IPSET_CMD "ipset"
+#define IPSET_BLACKLIST_NAME "ifw_bl"
+#define IPSET_WHITELIST_NAME "ifw_wl"
+#define IPSET_BLACKLIST_TIMEOUT "3600"
+
+#include <sys/types.h>
+
+void ipset_init();
+void ipset_destroy();
+/* void ipset_blacklist_load(char *filename); */
+/* void ipset_blacklist_save(char *filename); */
+/* void ipset_whitelist_load(char *filename); */
+/* void ipset_whitelist_save(char *filename); */
+void ipset_blacklist_add(u_int32_t addr);
+void ipset_blacklist_remove(u_int32_t addr);
+void ipset_whitelist_add(u_int32_t addr);
+void ipset_whitelist_remove(u_int32_t addr);
+
+#endif /* IPSET_H */
diff --git a/src/plugins/ifw/libnl_ifw.c b/src/plugins/ifw/libnl_ifw.c
new file mode 100644
index 0000000..bb41363
--- /dev/null
+++ b/src/plugins/ifw/libnl_ifw.c
@@ -0,0 +1,62 @@
+/* nl_create_socket(), nl_bind_socket() and nl_read_msg()
+ * for Interactive Firewall
+ * sbellabes@mandriva.com
+ */
+
+
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "libnl_ifw.h"
+
+int nl_ifw_bind_socket(int s) {
+ struct sockaddr_nl saddr_nl;
+ int res;
+
+ memset(&saddr_nl, 0, sizeof(struct sockaddr_nl));
+ saddr_nl.nl_family = AF_NETLINK;
+ saddr_nl.nl_pid = getpid();
+ saddr_nl.nl_groups = 10;
+
+ res = bind(s, (struct sockaddr *)&saddr_nl, sizeof(saddr_nl));
+ if (res == -1) {
+ perror("nl_bind_socket");
+ return -1;
+ }
+ return 1;
+}
+
+int nl_ifw_create_socket(void) {
+ int s;
+
+ s = socket(PF_NETLINK, SOCK_RAW, NETLINK_IFWLOG);
+ if (s < 0) {
+ perror("nl_create_socket");
+ return -1;
+ }
+
+ if (nl_ifw_bind_socket(s) < 0) {
+ close(s);
+ fprintf(stderr, "bind failed\n");
+ return -1;
+ }
+
+ return s;
+}
+
+int nl_ifw_read_msg(int s, struct nlmsghdr *nlh, struct nl_msg *msg) {
+ char buf[sizeof(struct nlmsghdr) + sizeof(struct nl_msg)];
+ int ret;
+
+ ret = recv(s, &buf, sizeof(buf), 0);
+ if (ret > 0) {
+ if (nlh) memcpy(nlh, buf, sizeof(struct nlmsghdr));
+ if (msg) memcpy(msg, NLMSG_DATA(buf), sizeof(struct nl_msg));
+ }
+
+ return ret;
+}
diff --git a/src/plugins/ifw/libnl_ifw.h b/src/plugins/ifw/libnl_ifw.h
new file mode 100644
index 0000000..896d05c
--- /dev/null
+++ b/src/plugins/ifw/libnl_ifw.h
@@ -0,0 +1,35 @@
+/*
+ * libnl_ifw.h
+ */
+
+#ifndef _LIBNL_IFW_H
+#define _LIBNL_IFW_H
+
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp.h>
+#include <netinet/udp.h>
+#include <linux/if.h>
+#include <linux/netlink.h>
+
+#define NETLINK_IFWLOG 19
+
+#define PREFSIZ 32
+
+struct nl_msg { /* Netlink kernel to user message */
+ long timestamp_sec; /* time packet */
+ char indev_name[IFNAMSIZ]; /* name of the ingoing interface */
+ char outdev_name[IFNAMSIZ]; /* name of the outgoing interface */
+ unsigned char prefix[PREFSIZ]; /* logging informations */
+ struct iphdr ip;
+ union {
+ struct tcphdr th;
+ struct udphdr uh;
+ } h;
+};
+
+int nl_ifw_bind_socket(int s);
+int nl_ifw_create_socket(void);
+int nl_ifw_read_msg(int s, struct nlmsghdr *nlh, struct nl_msg *msg);
+
+#endif /* !_LIBNL_IFW_H */
diff --git a/src/plugins/ifw/list.h b/src/plugins/ifw/list.h
new file mode 100644
index 0000000..1b55f95
--- /dev/null
+++ b/src/plugins/ifw/list.h
@@ -0,0 +1,155 @@
+#ifndef LIST_H
+#define LIST_H
+
+/* borrowed from kernel header linux/list.h */
+
+#define LIST_POISON1 ((void *) 0x00100100)
+#define LIST_POISON2 ((void *) 0x00200200)
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+ struct list_head *prev,
+ struct list_head *next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head * prev, struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ entry->next = LIST_POISON1;
+ entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ container_of(ptr, type, member)
+
+/**
+ * __list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+
+/* borrowed from kernel header linux/kernel.h */
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ *
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - linux_offsetof(type,member) );})
+
+
+/* borrowed from linux/stdddef.h */
+
+#define linux_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+
+#endif /* LIST_H */
diff --git a/src/plugins/ifw/plugin.c b/src/plugins/ifw/plugin.c
new file mode 100644
index 0000000..0e6ac69
--- /dev/null
+++ b/src/plugins/ifw/plugin.c
@@ -0,0 +1,224 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+#include "ifw.h"
+#include "ifw_dbus.h"
+#include "ipset.h"
+
+static int init(plugin_t *plugin, DBusConnection *connection);
+static void deinit(plugin_t *plugin, DBusConnection *connection);
+static void process_attack(plugin_t *plugin, DBusConnection *connection, int seq, msg_usr_t *attack);
+static DBusHandlerResult handle_message(DBusConnection *connection, DBusMessage *message, plugin_t *plugin);
+#ifdef IFW_FAKE
+static int generate_fake_attack(msg_usr_t *attack);
+static void handle_fake(plugin_t *plugin, DBusConnection *connection);
+#else
+static void handle_incoming(plugin_t *plugin, DBusConnection *connection);
+#endif
+
+static int init(plugin_t *plugin, DBusConnection *connection) {
+ ifw_t *ifw;
+
+ ifw = malloc(sizeof(ifw_t));
+ if (!ifw) {
+ fprintf(stderr, "unable to malloc ifw\n");
+ return -1;
+ }
+
+ report_list_init(&ifw->reports);
+ black_list_init(&ifw->blacklist);
+ white_list_init(&ifw->whitelist);
+ white_list_load(&ifw->whitelist, IFW_WHITELIST_FILENAME);
+
+ ifw->mode = IFW_MODE_INTERACTIVE;
+
+#ifdef IFW_FAKE
+ plugin->fd = 0;
+#else
+ plugin->fd = nl_ifw_create_socket();
+ if (plugin->fd < 0) {
+ fprintf(stderr, "unable to init netlink\n");
+ return -1;
+ }
+#endif
+
+ ifw_dbus_notify_clear(connection);
+ ifw_dbus_notify_init(connection);
+
+ plugin->priv = (void *) ifw;
+
+ return 0;
+}
+
+static void deinit(plugin_t *plugin, DBusConnection *connection) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+
+ ifw_dbus_notify_clear(connection);
+ close(plugin->fd);
+}
+
+#ifdef IFW_FAKE
+#include <time.h>
+
+static int generate_fake_attack(msg_usr_t *attack) {
+ static int seq = 0;
+ uint32_t addr = 0xC0A86401;
+
+ time(&attack->timestamp_sec);
+ strcpy(attack->indev_name, "ppp0");
+ attack->sensor = 0;
+ attack->protocol = 0;
+ attack->icmp_type = 0;
+ attack->d_port = 0;
+ attack->s_addr = htonl(addr);
+
+ switch(seq%3) {
+ case 0:
+ strcpy(attack->prefix, "SCAN");
+ break;
+ case 1:
+ strcpy(attack->prefix, "SERV");
+ attack->d_port = 22;
+ break;
+ case 2:
+ strcpy(attack->prefix, "PASS");
+ break;
+ }
+
+ addr++;
+ seq++;
+
+ return seq;
+}
+
+static void handle_fake(plugin_t *plugin, DBusConnection *connection) {
+ msg_usr_t fake_attack;
+ int seq;
+
+ read(0, NULL, 1);
+
+ seq = generate_fake_attack(&fake_attack);
+ printf("seq : %d\n", seq);
+
+ process_attack(plugin, connection, seq, &fake_attack);
+}
+
+#else
+
+static void handle_incoming(plugin_t *plugin, DBusConnection *connection) {
+ struct nl_msg msg;
+ static int seq = 0;
+ msg_usr_t attack;
+
+ if (nl_ifw_read_msg(plugin->fd, NULL, &msg) <= 0) {
+ fprintf(stderr, "unable to read packet from netlink\n");
+ return;
+ }
+
+ attack.timestamp_sec = msg.timestamp_sec;
+ strncpy(attack.indev_name, msg.indev_name, IFNAMSIZ);
+ strncpy(attack.prefix, (char *) msg.prefix, PREFSIZ);
+ attack.sensor = 0;
+ attack.protocol = msg.ip.protocol;
+ attack.s_addr = msg.ip.saddr;
+ switch (msg.ip.protocol) {
+ case IPPROTO_TCP:
+ attack.d_port = msg.h.th.dest;
+ break;
+ case IPPROTO_UDP:
+ attack.d_port = msg.h.uh.dest;
+ break;
+ default:
+ attack.d_port = 0;
+ break;
+ }
+ attack.icmp_type = 0;
+
+ process_attack(plugin, connection, seq++, &attack);
+}
+
+#endif
+
+static void process_attack(plugin_t *plugin, DBusConnection *connection, int seq, msg_usr_t *attack) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+ report_list_cell_t *report;
+
+ if (black_list_find(&ifw->blacklist, attack->s_addr) ||
+ white_list_find(&ifw->whitelist, attack->s_addr) ||
+ report_list_find(&ifw->reports, attack->s_addr, 0)) {
+ struct in_addr addr;
+ addr.s_addr = attack->s_addr;
+ fprintf(stderr, "skipping known address: %s\n", inet_ntoa(addr));
+ return;
+ }
+
+ if (!strcmp(attack->indev_name, "lo")) {
+ fprintf(stderr, "skipping loopback interface\n");
+ return;
+ }
+
+ report = report_list_add(&ifw->reports, seq, attack);
+ if (report) {
+ if (ifw->mode == IFW_MODE_AUTO) {
+ /* add ip address in ipset blacklist */
+ ifw_dbus_apply_report_verdict(connection, ifw, report, 1);
+ }
+
+ /* notify the attack to frontends */
+ ifw_dbus_notify_attack(connection, report);
+ }
+
+ black_list_print(&ifw->blacklist);
+ white_list_print(&ifw->whitelist);
+ report_list_print(&ifw->reports);
+}
+
+static DBusHandlerResult handle_message(DBusConnection *connection, DBusMessage *message, plugin_t *plugin) {
+ ifw_t *ifw = (ifw_t *) plugin->priv;
+ if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetMode")) {
+ return ifw_dbus_get_mode(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SetMode")) {
+ return ifw_dbus_set_mode(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetReports")) {
+ return ifw_dbus_get_reports(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetBlacklist")) {
+ return ifw_dbus_get_blacklist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SetBlacklistVerdict")) {
+ return ifw_dbus_set_blacklist_verdict(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "UnBlacklist")) {
+ return ifw_dbus_unblacklist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "GetWhitelist")) {
+ return ifw_dbus_get_whitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "Whitelist")) {
+ return ifw_dbus_whitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "UnWhitelist")) {
+ return ifw_dbus_unwhitelist(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "ClearProcessedReports")) {
+ return ifw_dbus_clear_processed_reports(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SendAlertAck")) {
+ return ifw_dbus_send_alert_ack(connection, message, ifw);
+ } else if (dbus_message_is_method_call(message, IFW_DBUS_INTERFACE, "SendManageRequest")) {
+ return ifw_dbus_send_manage_request(connection, message, ifw);
+ }
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+plugin_t ifw_plugin = {
+ .name = "Interactive Firewall",
+ .path = IFW_DBUS_PATH,
+ .init = init,
+#ifdef IFW_FAKE
+ .handle_incoming = handle_fake,
+#else
+ .handle_incoming = handle_incoming,
+#endif
+ .handle_message = handle_message,
+ .deinit = deinit,
+};
diff --git a/src/plugins/ifw/report_list.c b/src/plugins/ifw/report_list.c
new file mode 100644
index 0000000..c21df7e
--- /dev/null
+++ b/src/plugins/ifw/report_list.c
@@ -0,0 +1,81 @@
+#include "report_list.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void report_list_init(report_list_t *list) {
+ INIT_LIST_HEAD(list);
+}
+
+report_list_cell_t *report_list_add(report_list_t *list, int seq, msg_usr_t *attack) {
+ report_list_cell_t *cell;
+
+ cell = malloc(sizeof(report_list_cell_t));
+ if (!cell) {
+ fprintf(stderr, "unable to alloc enough memory for report list cell, skipping\n");
+ return NULL;
+ }
+ cell->seq = seq;
+ cell->info = *attack;
+ cell->processed = 0;
+ INIT_LIST_HEAD(&cell->list);
+ list_add_tail(&cell->list, list);
+
+ return cell;
+}
+
+report_list_cell_t *report_list_find(report_list_t *list, u_int32_t addr, int include_processed) {
+ struct list_head *entry;
+
+ __list_for_each(entry, list) {
+ report_list_cell_t *cell;
+ cell = list_entry(entry, report_list_cell_t, list);
+ if (cell->info.s_addr == addr && include_processed || !cell->processed) {
+ return cell;
+ }
+ }
+
+ return NULL;
+}
+
+report_list_cell_t *report_list_find_seq(report_list_t *list, int seq) {
+ struct list_head *entry;
+
+ __list_for_each(entry, list) {
+ report_list_cell_t *cell;
+ cell = list_entry(entry, report_list_cell_t, list);
+ if (cell->seq == seq) {
+ return cell;
+ }
+ }
+
+ return NULL;
+}
+
+void report_list_remove(report_list_cell_t *cell) {
+ list_del(&cell->list);
+ free(cell);
+}
+
+void report_list_clear_processed(report_list_t *list) {
+ report_list_cell_t *cell, *n;
+
+ list_for_each_entry_safe(cell, n, list, list) {
+ if (cell->processed) {
+ report_list_remove(cell);
+ }
+ }
+}
+
+void report_list_print(report_list_t *list) {
+ struct list_head *entry;
+
+ printf("* report list {\n");
+ __list_for_each(entry, list) {
+ report_list_cell_t *cell;
+ cell = list_entry(entry, report_list_cell_t, list);
+ printf("%d,\n", cell->seq);
+ }
+ printf("} report list *\n");
+}
+
diff --git a/src/plugins/ifw/report_list.h b/src/plugins/ifw/report_list.h
new file mode 100644
index 0000000..626afed
--- /dev/null
+++ b/src/plugins/ifw/report_list.h
@@ -0,0 +1,24 @@
+#ifndef REPORT_LIST_H
+#define REPORT_LIST_H
+
+#include "list.h"
+typedef struct list_head report_list_t;
+
+#include "ifw.h"
+
+typedef struct {
+ struct list_head list;
+ int seq;
+ msg_usr_t info;
+ char processed;
+} report_list_cell_t;
+
+void report_list_init(report_list_t *list);
+report_list_cell_t *report_list_add(report_list_t *list, int seq, msg_usr_t *attack);
+report_list_cell_t *report_list_find(report_list_t *list, u_int32_t addr, int include_processed);
+report_list_cell_t *report_list_find_seq(report_list_t *list, int seq);
+void report_list_remove(report_list_cell_t *cell);
+void report_list_clear_processed(report_list_t *list);
+void report_list_print(report_list_t *list);
+
+#endif /* REPORT_LIST_H */
diff --git a/src/plugins/ifw/white_list.c b/src/plugins/ifw/white_list.c
new file mode 100644
index 0000000..4318abc
--- /dev/null
+++ b/src/plugins/ifw/white_list.c
@@ -0,0 +1,119 @@
+#include "white_list.h"
+#include "ipset.h"
+#include "ifw.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+
+void white_list_init(white_list_t *list) {
+ INIT_LIST_HEAD(list);
+}
+
+void white_list_add(white_list_t *list, u_int32_t addr) {
+ white_list_cell_t *cell;
+
+ cell = malloc(sizeof(white_list_cell_t));
+ if (!cell) {
+ fprintf(stderr, "unable to alloc enough memory for white list cell, skipping\n");
+ return;
+ }
+ cell->addr = addr;
+ INIT_LIST_HEAD(&cell->list);
+ list_add_tail(&cell->list, list);
+
+ ipset_whitelist_add(cell->addr);
+ white_list_save(list, IFW_WHITELIST_FILENAME);
+}
+
+white_list_cell_t *white_list_find(white_list_t *list, u_int32_t addr) {
+ struct list_head *entry;
+
+ __list_for_each(entry, list) {
+ white_list_cell_t *cell;
+ cell = list_entry(entry, white_list_cell_t, list);
+ if (cell->addr == addr) {
+ return cell;
+ }
+ }
+
+ return NULL;
+}
+
+void white_list_remove(white_list_t *list, u_int32_t addr) {
+ white_list_cell_t *cell, *n, *prev;
+
+ ipset_whitelist_remove(addr);
+
+ prev = NULL;
+ list_for_each_entry_safe(cell, n, list, list) {
+ if (prev)
+ free(prev);
+ if (cell->addr == addr) {
+ list_del(&cell->list);
+ prev = cell;
+ } else {
+ prev = NULL;
+ }
+ }
+ if (prev)
+ free(prev);
+
+ white_list_save(list, IFW_WHITELIST_FILENAME);
+}
+
+
+void white_list_print(white_list_t *list) {
+ struct list_head *entry;
+
+ printf("* white list {\n");
+ __list_for_each(entry, list) {
+ white_list_cell_t *cell;
+ struct in_addr addr;
+ cell = list_entry(entry, white_list_cell_t, list);
+ addr.s_addr = cell->addr;
+ printf("%s,\n", inet_ntoa(addr));
+ }
+ printf("} white list *\n");
+}
+
+void white_list_load(white_list_t *list, const char *filepath) {
+ FILE *fp;
+
+ fp = fopen(filepath, "r");
+ if (fp) {
+ char addr_str[16];
+ struct in_addr addr;
+ while (fscanf(fp, "%15s\n", addr_str) > 0) {
+ if (inet_aton(addr_str, &addr)) {
+ white_list_add(list, addr.s_addr);
+ printf("adding IP address in white list: %s\n", addr_str);
+ } else {
+ fprintf(stderr, "unable to parse IP address in white list: %s\n", addr_str);
+ }
+ }
+ } else {
+ fprintf(stderr, "unable to open white list file\n");
+ }
+}
+
+void white_list_save(white_list_t *list, const char *filepath) {
+ FILE *fp;
+ struct list_head *entry;
+
+ fp = fopen(filepath, "w+");
+ if (fp) {
+ __list_for_each(entry, list) {
+ white_list_cell_t *cell;
+ struct in_addr addr;
+ cell = list_entry(entry, white_list_cell_t, list);
+ addr.s_addr = cell->addr;
+ fprintf(fp, "%15s\n", inet_ntoa(addr));
+ printf("adding IP address in white list: %s\n", inet_ntoa(addr));
+ }
+ } else {
+ fprintf(stderr, "unable to write white list file\n");
+ }
+}
diff --git a/src/plugins/ifw/white_list.h b/src/plugins/ifw/white_list.h
new file mode 100644
index 0000000..564f5ee
--- /dev/null
+++ b/src/plugins/ifw/white_list.h
@@ -0,0 +1,23 @@
+#ifndef WHITE_LIST_H
+#define WHITE_LIST_H
+
+#include "list.h"
+
+#include <sys/types.h>
+
+typedef struct list_head white_list_t;
+
+typedef struct {
+ struct list_head list;
+ u_int32_t addr;
+} white_list_cell_t;
+
+void white_list_init(white_list_t *list);
+void white_list_add(white_list_t *list, u_int32_t addr);
+white_list_cell_t *white_list_find(white_list_t *list, u_int32_t addr);
+void white_list_remove(white_list_t *list, u_int32_t addr);
+void white_list_print(white_list_t *list);
+void white_list_load(white_list_t *list, const char *filepath);
+void white_list_save(white_list_t *list, const char *filepath);
+
+#endif /* WHITE_LIST_H */