#include <linux/netfilter/xt_cgroup.h>
#include <linux/netfilter/xt_nfacct.h>
#include <linux/netfilter/xt_iprange.h>
+#include <linux/netfilter/xt_NFQUEUE.h>
#include <linux/netfilter/xt_NFLOG.h>
#include <linux/netfilter_ipv6/ip6t_LOG.h>
#define IP6TC_IPRANGE "iprange"
#define IP6TC_LOG "LOG"
#define IP6TC_NFLOG "NFLOG"
+#define IP6TC_NFQUEUE "NFQUEUE"
#define IP6TC_MASK "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"
/* target */
typedef struct ip6t_log_info ip6t_log_info_t;
typedef struct xt_nflog_info ip6t_nflog_info_t;
+typedef struct xt_NFQ_info_v3 ip6t_nfqueue_info_t;
#define SIZE_ENTRY IP6T_ALIGN(sizeof(ip6t_entry_t))
#define SIZE_TCP_MATCH IP6T_ALIGN(sizeof(ip6t_entry_match_t)) + IP6T_ALIGN(sizeof(ip6t_tcp_info_t))
#define SIZE_TARGET IP6T_ALIGN(sizeof(ip6t_entry_target_t)) + IP6T_ALIGN(sizeof(int))
#define SIZE_TARGET_LOG IP6T_ALIGN(sizeof(ip6t_log_info_t))
#define SIZE_TARGET_NFLOG IP6T_ALIGN(sizeof(ip6t_nflog_info_t))
+#define SIZE_TARGET_NFQUEUE IP6T_ALIGN(sizeof(ip6t_nfqueue_info_t))
#define SIZE_TOTAL SIZE_ENTRY + SIZE_TCP_MATCH + SIZE_UDP_MATCH + SIZE_CGROUP_MATCH \
+ SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH + SIZE_TARGET \
- + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG
+ + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE
static unsigned int __add_match(const char *name, ip6t_entry_match_t *start,
int revision, size_t size, void *data)
return __add_target(IP6TC_NFLOG, start, 0, sizeof(ip6t_nflog_info_t), &nflog);
}
+static unsigned int __add_nfqueue_target(unsigned int queue_id, bool queue_bypass, ip6t_entry_target_t *start)
+{
+ /* nfqueue => "--queue-num --queue-bypass" */
+ ip6t_nfqueue_info_t nfqueue;
+ memset(&nfqueue, 0, sizeof(ip6t_nfqueue_info_t));
+ nfqueue.queuenum = queue_id;
+ nfqueue.flags = queue_bypass ? NFQ_FLAG_BYPASS : 0;
+ nfqueue.queues_total = 1;
+ /* target_nfqueue */
+ return __add_target(IP6TC_NFQUEUE, start, 3, sizeof(ip6t_nfqueue_info_t), &nfqueue);
+ }
+
static int __create_entry_data(unsigned char *entry, unsigned char *mask,
ip6tables_rule_s *rule)
{
e->next_offset += __add_nflog_target(rule->nflog_group,
rule->nflog_prefix, rule->nflog_range, rule->nflog_threshold, target);
break;
+ case IP6TABLES_ACTION_NFQUEUE:
+ e->next_offset += __add_nfqueue_target(rule->nfqueue_id, rule->nfqueue_bypass, target);
+ break;
default:
target->u.target_size = SIZE_TARGET;
if (rule->target && rule->target[0] != '\0')
#ifndef __STC_HELPER_IP6TABLES_H__
#define __STC_HELPER_IP6TABLES_H__
+#include <stdbool.h>
#include <libiptc/libip6tc.h>
#define RULE_SIZE 64
IP6TABLES_ACTION_DROP,
IP6TABLES_ACTION_LOG,
IP6TABLES_ACTION_NFLOG,
+ IP6TABLES_ACTION_NFQUEUE,
} ip6tables_target_action_e;
typedef struct {
char *nflog_prefix;
unsigned int nflog_range;
unsigned int nflog_threshold;
+ unsigned int nfqueue_id;
+ bool nfqueue_bypass;
} ip6tables_rule_s;
/**
#include <errno.h>
#include <string.h>
+#include <stdbool.h>
#include <stdlib.h>
#include <glib.h>
#include <arpa/inet.h>
#include <linux/netfilter/xt_cgroup.h>
#include <linux/netfilter/xt_nfacct.h>
#include <linux/netfilter/xt_iprange.h>
+#include <linux/netfilter/xt_NFQUEUE.h>
#include <linux/netfilter/xt_NFLOG.h>
#include <linux/netfilter_ipv4/ipt_LOG.h>
#define IPTC_IPRANGE "iprange"
#define IPTC_LOG "LOG"
#define IPTC_NFLOG "NFLOG"
+#define IPTC_NFQUEUE "NFQUEUE"
#define IPTC_MASK "255.255.255.255"
/* target */
typedef struct ipt_log_info ipt_log_info_t;
typedef struct xt_nflog_info ipt_nflog_info_t;
+typedef struct xt_NFQ_info_v3 ipt_nfqueue_info_t;
#define SIZE_ENTRY IPT_ALIGN(sizeof(ipt_entry_t))
#define SIZE_TCP_MATCH IPT_ALIGN(sizeof(ipt_entry_match_t)) + IPT_ALIGN(sizeof(ipt_tcp_info_t))
#define SIZE_TARGET IPT_ALIGN(sizeof(ipt_entry_target_t)) + IPT_ALIGN(sizeof(int))
#define SIZE_TARGET_LOG IPT_ALIGN(sizeof(ipt_log_info_t))
#define SIZE_TARGET_NFLOG IPT_ALIGN(sizeof(ipt_nflog_info_t))
+#define SIZE_TARGET_NFQUEUE IPT_ALIGN(sizeof(ipt_nfqueue_info_t))
#define SIZE_TOTAL SIZE_ENTRY + SIZE_TCP_MATCH + SIZE_UDP_MATCH + SIZE_CGROUP_MATCH \
+ SIZE_NFACCT_MATCH + SIZE_IPRANGE_MATCH + SIZE_TARGET \
- + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG
+ + SIZE_TARGET_LOG + SIZE_TARGET_NFLOG + SIZE_TARGET_NFQUEUE
static unsigned int __add_match(const char *name, ipt_entry_match_t *start,
int revision, size_t size, void *data)
return __add_target(IPTC_NFLOG, start, 0, sizeof(ipt_nflog_info_t), &nflog);
}
+static unsigned int __add_nfqueue_target(unsigned int queue_id, bool queue_bypass, ipt_entry_target_t *start)
+{
+ /* nfqueue => "--queue-num --queue-bypass" */
+ ipt_nfqueue_info_t nfqueue;
+ memset(&nfqueue, 0, sizeof(ipt_nfqueue_info_t));
+ nfqueue.queuenum = queue_id;
+ nfqueue.flags = queue_bypass ? NFQ_FLAG_BYPASS : 0;
+ nfqueue.queues_total = 1;
+ /* target_nfqueue */
+ return __add_target(IPTC_NFQUEUE, start, 3, sizeof(ipt_nfqueue_info_t), &nfqueue);
+}
+
static int __create_entry_data(unsigned char *entry, unsigned char *mask,
iptables_rule_s *rule)
{
e->next_offset += __add_nflog_target(rule->nflog_group,
rule->nflog_prefix, rule->nflog_range, rule->nflog_threshold, target);
break;
+ case IPTABLES_ACTION_NFQUEUE:
+ e->next_offset += __add_nfqueue_target(rule->nfqueue_id, rule->nfqueue_bypass, target);
+ break;
default:
target->u.target_size = SIZE_TARGET;
if (rule->target && rule->target[0] != '\0')
#ifndef __STC_HELPER_IPTABLES_H__
#define __STC_HELPER_IPTABLES_H__
+#include <stdbool.h>
#include <libiptc/libiptc.h>
#define RULE_SIZE 64
IPTABLES_ACTION_DROP,
IPTABLES_ACTION_LOG,
IPTABLES_ACTION_NFLOG,
+ IPTABLES_ACTION_NFQUEUE,
} iptables_target_action_e;
typedef struct {
char *nflog_prefix;
unsigned int nflog_range;
unsigned int nflog_threshold;
+ unsigned int nfqueue_id;
+ bool nfqueue_bypass;
} iptables_rule_s;
/**
#define RULE_NFLOG_PREFIX "nflog_prefix"
#define RULE_NFLOG_RANGE "nflog_range"
#define RULE_NFLOG_THRESHOLD "nflog_threshold"
+#define RULE_NFQUEUE_ID "nfqueue_id"
+#define RULE_NFQUEUE_BYPASS "nfqueue_bypass"
#define STC_IPTABLES_DBUS_ERROR_NAME "net.stc.iptables.Error.Failed"
STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
}
+ } else if (!g_strcmp0(key, RULE_NFQUEUE_ID)) {
+ if (rule->target_type == IPTABLES_ACTION_NFQUEUE) {
+ rule->nfqueue_id = g_variant_get_uint16(value);
+ STC_LOGD("%s: [%u]", RULE_NFQUEUE_ID, rule->nfqueue_id);
+ }
+
+ } else if (!g_strcmp0(key, RULE_NFQUEUE_BYPASS)) {
+ if (rule->target_type == IPTABLES_ACTION_NFQUEUE) {
+ rule->nfqueue_bypass = g_variant_get_boolean(value);
+ STC_LOGD("%s: [%u]", RULE_NFQUEUE_BYPASS, rule->nfqueue_bypass);
+ }
+
} else {
STC_LOGD("Unknown rule [%s]", key); //LCOV_EXCL_LINE
}
STC_LOGD("%s: [%u]", RULE_NFLOG_THRESHOLD, rule->nflog_threshold);
}
+ } else if (!g_strcmp0(key, RULE_NFQUEUE_ID)) {
+ if (rule->target_type == IP6TABLES_ACTION_NFQUEUE) {
+ rule->nfqueue_id = g_variant_get_uint16(value);
+ STC_LOGD("%s: [%u]", RULE_NFQUEUE_ID, rule->nfqueue_id);
+ }
+
+ } else if (!g_strcmp0(key, RULE_NFQUEUE_BYPASS)) {
+ if (rule->target_type == IP6TABLES_ACTION_NFQUEUE) {
+ rule->nfqueue_bypass = g_variant_get_boolean(value);
+ STC_LOGD("%s: [%u]", RULE_NFQUEUE_BYPASS, rule->nfqueue_bypass);
+ }
} else {
STC_LOGD("Unknown rule [%s]", key); //LCOV_EXCL_LINE
}