Add TCP flag matching
authorMateusz Majewski <m.majewski2@samsung.com>
Thu, 24 Dec 2020 10:48:29 +0000 (11:48 +0100)
committerMateusz Majewski <m.majewski2@samsung.com>
Thu, 14 Jan 2021 12:17:48 +0000 (13:17 +0100)
Change-Id: Ie085073134b9b7a1d6a4329dee84f37b2e1a243e

src/helper/helper-ip6tables.c
src/helper/helper-ip6tables.h
src/helper/helper-iptables.c
src/helper/helper-iptables.h
src/stc-iptables-util.c

index a8c429a48b7dd98f5598065b0a0ccf6dd3b9d5e7..6f81345b247c436296b5b1e765eef9c3f5c02dbe 100755 (executable)
@@ -147,6 +147,7 @@ static void __add_iprange(unsigned char *entry, unsigned int *size_match, ip6tab
 static unsigned int __add_port_match(ip6tables_protocol_type_e prot_type,
                ip6tables_port_type_e sport_type, unsigned short sport1, unsigned short sport2,
                ip6tables_port_type_e dport_type, unsigned short dport1, unsigned short dport2,
+               unsigned char tcp_flag_mask, unsigned char tcp_flag_compare,
                ip6t_entry_match_t *start)
 {
        switch (prot_type) {
@@ -186,6 +187,8 @@ static unsigned int __add_port_match(ip6tables_protocol_type_e prot_type,
                                tcp.dpts[1] = 0xFFFF;
                                break;
                        }
+                       tcp.flg_mask = tcp_flag_mask;
+                       tcp.flg_cmp = tcp_flag_compare;
                        return __add_match(IP6TC_TCP, start, 0, sizeof(ip6t_tcp_info_t), &tcp);
                }
        case IP6TABLES_PROTOCOL_UDP:
@@ -239,13 +242,16 @@ static void __add_port(unsigned char *entry, unsigned int *size_match,
        if ((rule->s_port_type > IP6TABLES_PORT_NONE &&
                rule->s_port_type <= IP6TABLES_PORT_RANGE) ||
                (rule->d_port_type > IP6TABLES_PORT_NONE &&
-               rule->d_port_type <= IP6TABLES_PORT_RANGE)) {
+               rule->d_port_type <= IP6TABLES_PORT_RANGE) ||
+               rule->tcp_flag_compare != 0 ||
+               rule->tcp_flag_mask != 0) {
 
                ip6t_entry_t *e = (ip6t_entry_t *)(entry);
 
                (*size_match) += __add_port_match(rule->protocol,
                        rule->s_port_type, rule->s_port1, rule->s_port2,
                        rule->d_port_type, rule->d_port1, rule->d_port2,
+                       rule->tcp_flag_mask, rule->tcp_flag_compare,
                        (ip6t_entry_match_t *) (e->elems + (*size_match)));
 
                e->target_offset += match_size;
index a4ff7f4dd2f069b6be90c080a3a16e11bbebad46..2b2baddffcc68438afbeb2cf78d1bda5400bcf0c 100755 (executable)
@@ -77,6 +77,8 @@ typedef struct {
        ip6tables_port_type_e s_port_type;
        ip6tables_port_type_e d_port_type;
        ip6tables_protocol_type_e protocol;
+       unsigned char tcp_flag_mask;
+       unsigned char tcp_flag_compare;
        struct in6_addr s_ip1;
        struct in6_addr s_ip2;
        struct in6_addr d_ip1;
index e4cc3ae8281e5bcbe25d3aa2265865601abbe3a2..9b10a02853de82a3895c9867991741f0e64a0767 100755 (executable)
@@ -146,6 +146,7 @@ static void __add_iprange(unsigned char *entry, unsigned int *size_match, iptabl
 static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                iptables_port_type_e sport_type, unsigned short sport1, unsigned short sport2,
                iptables_port_type_e dport_type, unsigned short dport1, unsigned short dport2,
+               unsigned char tcp_flag_mask, unsigned char tcp_flag_compare,
                ipt_entry_match_t *start)
 {
        switch (prot_type) {
@@ -185,6 +186,8 @@ static unsigned int __add_port_match(iptables_protocol_type_e prot_type,
                                tcp.dpts[1] = 0xFFFF;
                                break;
                        }
+                       tcp.flg_mask = tcp_flag_mask;
+                       tcp.flg_cmp = tcp_flag_compare;
                        return __add_match(IPTC_TCP, start, 0, sizeof(ipt_tcp_info_t), &tcp);
                }
        case IPTABLES_PROTOCOL_UDP:
@@ -238,13 +241,16 @@ static void __add_port(unsigned char *entry, unsigned int *size_match,
        if ((rule->s_port_type > IPTABLES_PORT_NONE &&
                rule->s_port_type <= IPTABLES_PORT_RANGE) ||
                (rule->d_port_type > IPTABLES_PORT_NONE &&
-               rule->d_port_type <= IPTABLES_PORT_RANGE)) {
+               rule->d_port_type <= IPTABLES_PORT_RANGE) ||
+               rule->tcp_flag_compare != 0 ||
+               rule->tcp_flag_mask != 0) {
 
                ipt_entry_t *e = (ipt_entry_t *)(entry);
 
                (*size_match) += __add_port_match(rule->protocol,
                        rule->s_port_type, rule->s_port1, rule->s_port2,
                        rule->d_port_type, rule->d_port1, rule->d_port2,
+                       rule->tcp_flag_mask, rule->tcp_flag_compare,
                        (ipt_entry_match_t *) (e->elems + (*size_match)));
 
                e->target_offset += match_size;
index 5c3e176b63ff859793518ecc28b2f3ecbcd60e30..9a1f236761b2494d10bca7dae4529fdda6ccd5f0 100755 (executable)
@@ -77,6 +77,8 @@ typedef struct {
        iptables_port_type_e s_port_type;
        iptables_port_type_e d_port_type;
        iptables_protocol_type_e protocol;
+       unsigned char tcp_flag_mask;
+       unsigned char tcp_flag_compare;
        struct in_addr s_ip1;
        struct in_addr s_ip2;
        struct in_addr d_ip1;
index 54902cff489dcae137e9c841417a168f78103139..91574af2c837f784a924edbc5a8c88ba6b86310a 100755 (executable)
@@ -31,6 +31,8 @@
 #define RULE_CGROUP     "cgroup"
 #define RULE_NFACCT     "nfacct"
 #define RULE_PROTOCOL   "protocol"
+#define RULE_MASK       "tcp_flag_mask"
+#define RULE_COMPARE    "tcp_flag_compare"
 #define RULE_TARGET     "target"
 #define RULE_TARGETTYPE "target_type"
 
@@ -175,6 +177,18 @@ void __stc_extract_rule(const char *key, GVariant *value,
                rule->protocol = g_variant_get_uint16(value);
                STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol);
 
+       } else if (!g_strcmp0(key, RULE_MASK)) {
+               if (rule->protocol == IPTABLES_PROTOCOL_TCP) {
+                       rule->tcp_flag_mask = g_variant_get_byte(value);
+                       STC_LOGD("%s: [%u]", RULE_MASK, rule->tcp_flag_mask);
+               }
+
+       } else if (!g_strcmp0(key, RULE_COMPARE)) {
+               if (rule->protocol == IPTABLES_PROTOCOL_TCP) {
+                       rule->tcp_flag_compare = g_variant_get_byte(value);
+                       STC_LOGD("%s: [%u]", RULE_COMPARE, rule->tcp_flag_compare);
+               }
+
        } else if (!g_strcmp0(key, RULE_TARGET)) {
                gsize len = 0;
                rule->target = g_variant_dup_string(value, &len);
@@ -355,6 +369,18 @@ void __stc_extract_6_rule(const char *key, GVariant *value,
                rule->protocol = g_variant_get_uint16(value);
                STC_LOGD("%s: [%u]", RULE_PROTOCOL, rule->protocol);
 
+       } else if (!g_strcmp0(key, RULE_MASK)) {
+               if (rule->protocol == IP6TABLES_PROTOCOL_TCP) {
+                       rule->tcp_flag_mask = g_variant_get_byte(value);
+                       STC_LOGD("%s: [%u]", RULE_MASK, rule->tcp_flag_mask);
+               }
+
+       } else if (!g_strcmp0(key, RULE_COMPARE)) {
+               if (rule->protocol == IP6TABLES_PROTOCOL_TCP) {
+                       rule->tcp_flag_compare = g_variant_get_byte(value);
+                       STC_LOGD("%s: [%u]", RULE_COMPARE, rule->tcp_flag_compare);
+               }
+
        } else if (!g_strcmp0(key, RULE_TARGET)) {
                gsize len = 0;
                rule->target = g_variant_dup_string(value, &len);